详解Spring依赖注⼊:@Autowired,@Resource和
@Inject区别与实现原理
⼀、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 ioc注解
在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⽂件中,如l,添加<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配置
如果是基于配置类⽽不是基于l来对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⼀起使⽤。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。