前言

Spring中支持三种注入方式,分别是构造器注入,属性注入,方法注入,这三者之间的优缺点本文不做阐述,有兴趣的可以参考这两篇文章,我觉得写的不错,Setter injection vs constructor injection 浅谈spring为什么推荐使用构造器注入。 其中,构造器注入发生在createBeanInstance期间,而属性注入和方法注入则发生在populateBean期间,整个getBean的时序图大致如下:

Java standard annotation

@Inject

最常见也是最常用的注解,JSR-330中引入,Spring在AutowiredAnnotationBeanPostProcessor中实现了对@Inject的支持,AutowiredAnnotationBeanPostProcessor是InstantiationAwareBeanPostProcessor的一种实现。 其中属性注入是通过AutowiredFieldElement,方法注入是通过AutowiredMethodElement,实现方式实际上与@Autowired一样,顺带说一句@Value也是在这里实现的。

@Resource

JSR-250中引入的注解,Spring在CommonAnnotationBeanPostProcessor中实现了对@Resource的支持。 @Resource的实现方式与@Inject略有不同,并不是通过重写InjectedElement.inject而是重写了InjectedElement.getResourceToInject。

Non Java standard annotation

@Autowired

@Autowired是Spring自己提供的annotation,其功能几乎与@Inject相同,实现也一样,在上文中已经解释过,顺带说一句,能用@Inject就不要用@Autowired,毕竟@Autowired是与Spring绑定在一起的。

总结

  • @Autowired通过类型进行注入,如果该类型有多种实现,则需要通过@Qualifier指定bean name,如果没有找到@Qualifier,则默认使用field name
  • @Inject与@Autowired几乎没什么使用上的区别,除了@Autowired允许null(即required=false)
  • @Resource与前面两种不一样的是优先使用name注入,如果找不到对应的bean则尝试通过type注入,最后才会使用@Qualifier(如果有的话)