@Autowired、@Resource和@Inject的区别

基本介绍

Spring中咱们可使用如下三个自动装配的注解进行依赖注入:java

  • @Autowired注解默认是按照类型(byType)装配依赖对象,默认状况下它要求依赖对象必须存在,当没有找到相应bean的时候,IOC容器就会报错。不过@Autowired有个required属性,能够配置为false,若是配置为false以后,当没有找到相应bean的时候就注入null,系统不会抛错。若是咱们想使用按照名称(byName)来装配,能够结合@Qualifier注解一块儿使用。spring

  • @Resource默认按照名字(byName)装配依赖对象,由JAVAEE提供,须要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。因此,若是使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。若是既不制定name也不制定type属性,这时将经过反射机制使用byName自动注入策略。bash

  • @Inject注解默认也是按照类型(byType)装配依赖对象,若是须要按名称进行装配,则须要配合@Named注解。@Inject 注解没有 required 属性,所以在找不到合适的依赖对象时 inject 会系统会报错失败。 使用 @Inject 须要添加以下依赖:app

<dependency>
	<groupId>javax.inject</groupId>
	<artifactId>javax.inject</artifactId>
	<version>1</version>
  </dependency>
复制代码

实现原理

注解处理器

        在Spring框架内部实现当中,注解实现注入主要是经过bean后置处理器BeanPostPocessor接口的实现类来生效的。BeanPostProcessor后置处理器是在spring容器启动时,建立bean对象实例后,立刻执行的,对bean对象实例进行加工处理。         框架

  • @Autowired是经过BeanPostProcessor接口的实现类AutowiredAnnotationBeanPostProcessor来实现对bean对象对其余bean对象的依赖注入的;ui

  • @Resource和@Inject是经过BeanPostProcessor接口的实现类CommonAnnotationBeanPostProcessor来实现的,顾名思义即公共注解CommonAnotation,CommonAnnotationBeanPostProcessor是Spring中统一处理JDK中定义的注解的一个BeanPostProcessor。该类会处理的注解还包括@PostConstruct,@PreDestroy等。spa

注解处理器的激活条件

AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor添加到Spring容器的BeanPostProcessor的条件,即激活这些处理器的条件以下:code

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方式,则是当前类所在包及其子包下面。component

2. 基于配置类的Spring配置

若是是基于配置类而不是基于applicationContext.xml来对Spring进行配置,如SpringBoot,则在内部使用的IOC容器实现为AnnotationConfigApplicationContext或者其派生类,在AnnotationConfigApplicationContext内部会自动建立和激活以上的BeanPostProcessor。 若是同时存在基于xml的配置和配置类的配置,而在注入时间方面,基于注解的注入先于基于XML的注入,因此基于XML的注入会覆盖基于注解的注入。cdn

三个注解的异同

  1. @Autowired是Spring自带的,@Inject和@Resource都是JDK提供的,其中@Inject是JSR330规范的实现,@Resource是JSR250规范的实现。
  2. @Autowired和@Inject基本是同样的,由于二者都是使AutowiredAnnotationBeanPostProcessor来处理依赖注入。可是@Resource不同,它使用的是CommonAnnotationBeanPostProcessor来处理依赖注入。固然,二者都是BeanPostProcessor。
  3. @Autowired和@Inject主要区别是@Autowired能够设置required属性为false,而@Inject并无这个设置选项。
  4. @Resource默认是按照byName进行注入,而@Autowired和@Inject默认是按照byType进行注入。
  5. @Autowired经过@Qualifier指定注入特定bean,@Resource能够经过参数name指定注入bean,@Inject须要@Named注解指定注入bean。
相关文章
相关标签/搜索