Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理
程序员文章站
2022-06-19 16:45:27
一、spring依赖注入使用方式 @Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byType的,如果存在多个同一类型的bean,则使用@Qualifier来指定注入哪个beanName的 ......
一、spring依赖注入使用方式
- @autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即bytype的,如果存在多个同一类型的bean,则使用@qualifier来指定注入哪个beanname的bean。
- 与jdk的@resource的区别:@resource是基于bean的名字,即beanname,来从spring的ioc容器查找bean注入的,而@autowried是基于类型bytype来查找bean注入的。
- 与jdk的@inject的区别:@inject也是基于类型来查找bean注入的,如果需要指定名称beanname,则可以结合使用@named注解,而@autowired是结合@qualifier注解来指定名称beanname。
二、spring依赖注入注解的实现原理
注解处理器
- 在spring框架内部实现当中,注解实现注入主要是通过bean后置处理器beanpostprocessor接口的实现类来生效的。beanpostprocessor后置处理器是在spring容器启动时,创建bean对象实例后,马上执行的,对bean对象实例进行加工处理。
- @autowired是通过beanpostprocessor接口的实现类autowiredannotationbeanpostprocessor来实现对bean对象对其他bean对象的依赖注入的;
- @resource和@inject是通过beanpostprocessor接口的实现类commonannotationbeanpostprocessor来实现的,其中如名字所述,即公共注解commonanotation,commonannotationbeanpostprocessor是spring中统一处理jdk中定义的注解的一个beanpostprocessor。该类会处理的注解还包括@postconstruct,@predestroy等。
注解处理器的激活条件
autowiredannotationbeanpostprocessor和commonannotationbeanpostprocessor添加到spring容器的beanpostprocessor的条件,即激活这些处理器的条件如下:
1.基于xml的spring配置
- 在对应的spring容器的配置xml文件中,如applicationcontext.xml,添加<context:annotation-config />和<context:component-scan />,或者只使用<context:component-scan />。
- 两者的区别是<context:annotation-config />只查找并激活已经存在的bean,如通过xml文件的bean标签生成加载到spring容器的,而不会去扫描如@controller等注解的bean,查找到之后进行注入;而<context:component-scan />除了具有<context:annotation-config />的功能之外,还会去加载通过basepackages属性指定的包下面的,默认为扫描@controller,@service,@component,@repository注解的类。不指定basepackages则是类路径下面,或者如果使用注解@componentscan方式,则是当前类所在包及其子包下面。
2.基于配置类的spring配置
- 如果是基于配置类而不是基于applicationcontext.xml来对spring进行配置,如springboot,则在内部使用的ioc容器实现为annotationconfigapplicationcontext或者其派生类,在annotationconfigapplicationcontext内部会自动创建和激活以上的beanpostprocessor。
- 如果同时存在基于xml的配置和配置类的配置,而在注入时间方面,基于注解的注入先于基于xml的注入,所以基于xml的注入会覆盖基于注解的注入。
三、总结
- @autowired是spring自带的,@inject和@resource都是jdk提供的,其中@inject是jsr330规范实现的,@resource是jsr250规范实现的,而spring通过beanpostprocessor来提供对jdk规范的支持。
- @autowired、@inject用法基本一样,不同之处为@autowired有一个required属性,表示该注入是否是必须的,即如果为必须的,则如果找不到对应的bean,就无法注入,无法创建当前bean。
- @autowired、@inject是默认按照类型匹配的,@resource是按照名称匹配的。如在spring-boot-data项目中自动生成的redistemplate的bean,是需要通过byname来注入的。如果需要注入该默认的,则需要使用@resource来注入,而不是@autowired。
- 对于@autowire和@inject,如果同一类型存在多个bean实例,则需要指定注入的beanname。@autowired和@qualifier一起使用,@inject和@name一起使用。