您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

spring注入你真搞懂了吗?不会一直都是这样错误理解吧?

时间:2020-09-09 12:40:04  来源:  作者:

说起spring的注入,可能大家都有了解。可你认知几种注入方式呢?你所认知的注入方式是否正确呢?我估计大多数人了解注入方式不全面,并且还会曲解一些概念。今天我们就参考最权威的官网来具体谈谈spring的注入方式。

这里想给大家复习一下Spring的基础知识,对于后续理解有很大帮助

IOC&&DI

想必关于这两个概念大家不会陌生,面试题经常会出现的。这里我们就从官网详细文档看一看。

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

详细的翻译具体概念我就不讲了,在这我只说出自己的理解

其实IOC也被称为DI,因为在spring中IOC作用就是不需要程序员来手动创建和管理JAVA类,而是由spring容器自动实例化Bean对象。怎么个IOC呢,其实就是通过DI(依赖注入)实现的。

补充一点关于spring的bean对象(后面简称bean)
其实bean对象就是java对象,不同的在于Bean对象是由spring创建管理对象。
bean对象 是 java对象,但java对象 不一定是 bean对象

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 


我们的业务类,经过spring容器DI添加源数据从而生成一个Bean对象可以被使用。这也就是spring IOC容器的运行流程图。

Configuration Metadata(IOC)

关于配置元数据,spring官方文档给出了三种配置方式

  1. XML-based metadata 1.0版本
  2. Annotation-based configuration 2.5版本
  3. Java-based configuration 3.0版本

虽说三种,但其实我接触也只有前两种。本文也是关于前两种详细介绍。

基于 XML 的 bean 注入方式

xml手动配置bean (自动装配可以通过set方法自动创建pojo类对象加上元数据信息构造成bean对象)

基于 XML 的 bean 注入方式的实现有三种方法:

  1. xml配置ref
  2. 属性 setter方法注入(或设值注入)
  3. 构造方法注入

在基于 XML 的 bean 装配中,我们需要了解一下自动注入模型

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

关于自动模型官网上解释说:当使用基于xml的注入方式时,可以指定自动连接模式
也就是说spring 的自动注入的模型 (仅仅针对xml-based配置)
使用java,annotation另外两种注入方式没有注入模型

Autowiring Collaborators(自动注入的模型)

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

  1. no :(默认)没有自动装配。Bean引用必须由ref元素定义。
  2. byname:通过名称查找bean自动装配属性。
  3. bytype:通过类型找bean,根据set或者构造方法注入
  4. construct 推断构造方法 通过构造方法自动配置,如果多个构造方法选择多个参数的构造方法

Annotation-based configuration(注解注入)

@Autowired和@Resource两个注解实现。面试题中也经常会问到两个注解的区别,我搜索网上的答案却讲的是@Autowired是通过bytype,@Resource是通过byname。但这种理解显然是错误的,因为关于自动模型文章前面也已经说过 官网:当使用基于xml的注入方式时,可以指定自动连接模式

@Autowired和@Resource只不过是通过type,name去查找,而不是bytype以及byname模式。有什么区别?
区别在于byname通过名字找bean自动填充–>没找到就会报错
bytype通过类型去找bean自动填充–>没找到就会报错

1. @Autowired:type --> name --> error
不仅仅通过type找。type找不到,还可以通过name找。都找不到才会报错
spring包中的AutowiredAnnotationBeanPostProcessor.java中的一个方法实现解析的
2. @Resource:name --> type --> error
不仅仅通过name找。name找不到,还可以通过type找。都找不到才会报错
javax中的 commonAnnotationBeanPostProcessor.java中的一个方法实现解析的

这里再强调一下:
注解 无关注入的模型(no,byname,bytype,constract)

怎么说?还相信网上的知识点吗?不相信我说的?那可以我们还是来用code证明。

Talk is cheap,show you my code

准备阶段

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

  1. 创建一个spring项目
  2. 创建Appconfig类以及test类
  3. 创建几个service类

Appconfig.java

package services;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
@Configurable
@ComponentScan("com.shadow")
public class Appconfig {

Test.java

package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
    public static void main(String[] args) {
//        AnnotationConfigApplicationContext ac =
//                new AnnotationConfigApplicationContext(Appconfig.class);
        ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("web.xml");
    }
}

其余都为空

基于 XML 的 bean 注入方式

no方式配置

GoudanService.java

package services;
public class GoudanService {
    GouService gouService;    public void setGouService(GouService gouService) {
        this.gouService = gouService;
    }    public GouService getGouService() {
        return gouService;
    }}

web.xml

<bean id="goudanBean" class="services.GoudanService">
        <property name="gouService">
            <ref bean="gouBean"></ref>
        </property>
    </bean>
    <bean id="gouBean" class="services.GouService">
    </bean>

Test.java

package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import services.GoudanService;
public class Test {
    public static void main(String[] args) {
//        AnnotationConfigApplicationContext ac =
//                new AnnotationConfigApplicationContext(Appconfig.class);
        ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("web.xml");
        System.out.println(cc.getBean(GoudanService.class).getGouService());
    }
}

运行Test.java的result

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

想要在GoudanService中配置GouService,我们采用xml配置方式的no注入模型。虽然我们没有配置注入模型参数但是xml默认是no。故所以我们运行Test.java得出结果是配置成功的。

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 


我把xml这一段注释掉呢?
根据no注入模型的官网解释,大家应该知道这是无法自动配置的,也就是null。

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

bytype方式配置

GoudanService.java

package services;
public class GoudanService {
    GouService gouService;    public void setGouService(GouService gouService) {
        this.gouService = gouService;
    }    public GouService getGouService() {
        return gouService;
    }}

web.xml

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

	<bean id="goudanBean" class="services.GoudanService">
	    </bean>
    <bean id="gouBean" class="services.GouService">
    </bean>

Test.java

package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import services.GoudanService;
public class Test {
    public static void main(String[] args) {
//        AnnotationConfigApplicationContext ac =
//                new AnnotationConfigApplicationContext(Appconfig.class);
        ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("web.xml");
        System.out.println(cc.getBean(GoudanService.class).getGouService());
    }
}

运行Test.java的result

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

我们发现bytype模型注入,与no方式注入想比不需要了bean里配置property的ref,spring容器会自动根据GouService的类型去找bean,结果找到了类型为:services.GouService的bean,所以也是可以配置成功的。

重点:bytype就是如果属性类型与bean的class类型相同那么可以自动配置,否则配置错误。看下面图

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 


spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

byname方式配置

GoudanService.java

package services;
public class GoudanService {
    GouService gouService;    GouService gouBean;    public GouService getGouBean() {
        return gouBean;
    }    public void setGouBean(GouService gouBean) {
        this.gouBean = gouBean;
    }    public void setGouService(GouService gouService) {
        this.gouService = gouService;
    }    public GouService getGouService() {
        return gouService;
    }}

web.xml

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

	<bean id="goudanBean" class="services.GoudanService">
	    </bean>
    <bean id="gouBean" class="services.GouService">
    </bean>

Test.java

package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import services.GoudanService;
public class Test {
    public static void main(String[] args) {
//        AnnotationConfigApplicationContext ac =
//                new AnnotationConfigApplicationContext(Appconfig.class);
        ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("web.xml");
//        System.out.println(cc.getBean(GoudanService.class).getGouService());
        System.out.println(cc.getBean(GoudanService.class).getGouBean());
    }
}

运行Test.java的result

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

我们发现byname模型注入,与no方式注入想比不需要了bean里配置property的ref,spring容器会自动根据GouService定义属性名称去找bean的名称,结果找到了id名称为:gouBean的bean,所以也是可以配置成功的。

byname就是如果属性名称与bean的id名称相同那么可以自动配置,否则配置错误。

construct方式配置

GoudanService.java

package services;
public class GoudanService {
    GouService gouService;
    GouService gouBean;    //构造方法1
    GoudanService(GouService gouBean){        this.gouBean=gouBean;    }//    //构造方法2
//    GoudanService(GouService gouService){
//        this.gouService=gouService;
//    }
//    //构造方法3
//    GoudanService(GouService gouService,GouService gouBean){
//        this.gouService=gouService;
//        this.gouBean=gouBean;
//    }
    
    public GouService getGouBean() {
        return gouBean;
    }
    public GouService getGouService() {
        return gouService;
    }
//    public void setGouBean(GouService gouBean) {
//        this.gouBean = gouBean;
//    }
//    public void setGouService(GouService gouService) {
//        this.gouService = gouService;
//    }
}

web.xml

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

	<bean id="goudanBean" class="services.GoudanService">
	    </bean>
    <bean id="gouBean" class="services.GouService">
    </bean>

Test.java

package test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import services.GoudanService;
public class Test {
    public static void main(String[] args) {
//        AnnotationConfigApplicationContext ac =
//                new AnnotationConfigApplicationContext(Appconfig.class);
        ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("web.xml");
        System.out.println(cc.getBean(GoudanService.class).getGouService());
        System.out.println(cc.getBean(GoudanService.class).getGouBean());
    }
}

分别运行构造方法1,2,3三次,注释掉其他两种构造方法
运行Test.java的result

构造方法1

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

构造方法2

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

构造方法3

spring的注入你真搞懂了吗?不会一直都是这样错误理解吧?

 

我们发现construct模型注入,它既可以通过name注入也可以通过type注入。

Annotaton-based configuration(注解注入方式)

@Autowired

在这里,很多人网上说@Autowired是通过bytype查找,但其实这种说法有些许的不严谨。
1.自动注入模型是基于xml的bean注入方式。
2.bytype模型是只要通过类型查找,如果找不到,或者找到两个相同的类型bean就会报错
3.而@Autowired是通过类型去找,找不到还会通过名称去找

@Resource

而@Resource是通过byname查找,这种说法和@Autowired相似也是不严谨的。
byname模型是只要通过名称查找,如果找不到报错而@Resource是通过名称去找,找不到还会通过类型去找,不单单只限于通过name去查找。

区别

  1. @Autowired type --> name --> error
    spring包中的AutowiredAnnotationBeanPostProcessor.java中的一个方法实现解析的
  2. @Resource name --> type --> error
    javax中的 commonAnnotationBeanPostProcessor.java中的一个方法实现解析的

来源:https://blog.csdn.net/qq_40994080/article/details/108090104?utm_medium=distribute.pc_category.none-task-blog-hot-2.nonecase&depth_1-utm_source=distribute.pc_category.none-task-blog-hot-2.nonecase&request_id=


Tags:spring注入   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
说起spring的注入,可能大家都有了解。可你认知几种注入方式呢?你所认知的注入方式是否正确呢?我估计大多数人了解注入方式不全面,并且还会曲解一些概念。今天我们就参考最权威的...【详细内容】
2020-09-09  Tags: spring注入  点击:(56)  评论:(0)  加入收藏
▌简易百科推荐
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Python阿杰    Tags:FastAPI   点击:(6)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  java老人头    Tags:框架   点击:(11)  评论:(0)  加入收藏
今天来梳理下 Spring 的整体脉络啦,为后面的文章做个铺垫~后面几篇文章应该会讲讲这些内容啦 Spring AOP 插件 (了好久都忘了 ) 分享下 4ye 在项目中利用 AOP + MybatisPlus 对...【详细内容】
2021-12-07  Java4ye    Tags:Spring   点击:(14)  评论:(0)  加入收藏
&emsp;前面通过入门案例介绍,我们发现在SpringSecurity中如果我们没有使用自定义的登录界面,那么SpringSecurity会给我们提供一个系统登录界面。但真实项目中我们一般都会使用...【详细内容】
2021-12-06  波哥带你学Java    Tags:SpringSecurity   点击:(18)  评论:(0)  加入收藏
React 简介 React 基本使用<div id="test"></div><script type="text/javascript" src="../js/react.development.js"></script><script type="text/javascript" src="../js...【详细内容】
2021-11-30  清闲的帆船先生    Tags:框架   点击:(19)  评论:(0)  加入收藏
流水线(Pipeline)是把一个重复的过程分解为若干个子过程,使每个子过程与其他子过程并行进行的技术。本文主要介绍了诞生于云原生时代的流水线框架 Argo。 什么是流水线?在计算机...【详细内容】
2021-11-30  叼着猫的鱼    Tags:框架   点击:(21)  评论:(0)  加入收藏
TKinterThinter 是标准的python包,你可以在linx,macos,windows上使用它,你不需要安装它,因为它是python自带的扩展包。 它采用TCL的控制接口,你可以非常方便地写出图形界面,如...【详细内容】
2021-11-30    梦回故里归来  Tags:框架   点击:(26)  评论:(0)  加入收藏
前言项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文...【详细内容】
2021-11-17  充满元气的java爱好者  博客园  Tags:SpringBoot   点击:(25)  评论:(0)  加入收藏
一、搭建环境1、创建数据库表和表结构create table account(id INT identity(1,1) primary key,name varchar(20),[money] DECIMAL2、创建maven的工程SSM,在pom.xml文件引入...【详细内容】
2021-11-11  AT小白在线中  搜狐号  Tags:开发框架   点击:(29)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  小程序建站    Tags:SpringBoot   点击:(55)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条