Spring的注入方式大比拼

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Spring的注入方式大比拼

写在前面,原谅我图片党了。只是喜欢里边一句
“一知半解比一无所知更痛苦。”——West World

在使用Spirng 注入的时候,多数情况下都不会在xml中去定义了,而是以注解的方式去声明bean,然后声明依赖的bean,就像下面这样

Spring的注入方式大比拼

如此多的注入方式,你一定花了眼,貌似功能都差不多,但既然都同时存在,那就一定有它的区别,我们来看下区别在哪?

先看下这几个注解的出处

  • @Autowired @Qualifier都是spring专属的,注意@Qualifier有两个,上图中用到的是Spring的,还有一个javax.inject.Qualifier(JSR330)是用来自定义注解的,不能作用于field
  • @Resource 是出自JSR250 Declares a reference to a resource, e.g. a database

  • @Inject 出自JSR330

  • 知道了出处,再来看下在Spring中实现的细节

    Autowired

    这个注解的处理是在AutowiredAnnotationBeanPostProcessor

    这个类同时还处理了其它的@Inject @Value,所以这几个注解的查找依赖bean逻辑类似

    Spring的注入方式大比拼

    这段代码在DefaultListableBeanFactory中,它寻找依赖的过程大致如下

    根据根据在beanFactory中按类型查找可能被注入的bean,如果有一个类型定义了多个bean,那么返回的是beanName跟beanInstance的map

    Spring的注入方式大比拼

    判断返回map中bean个数:

  • 0个 抛 NoSuchBeanDefinitionException
  • 大于1个,则要去进一步筛选
  • 恰好有一个,直接选用
  • Spring的注入方式大比拼

    当大于1个的时候,进一步筛选逻辑

  • 先判断这些bean有没有primary的
  • 再判断它们有没有priority
  • 都没有的话,最后根据name匹配(beanFactory中的name与Autowired的属性名)
  • 如果都匹配不到,则返回null,上层方法会throw NoUniqueBeanDefinitionException

    Spring的注入方式大比拼

    Qulifier

    这个是作为一种@Autowired注入方式的一种补充,能在容器中声明了同一类型的多个bean的时候,根据Qualifier的注解中的value 去跟bean name匹配来限定注入哪一个bean,需要说明的是,这里做qualifier判定的时候,同时support了spring的Qualifier和javax.inject.Qulifier

    Spring的注入方式大比拼

    它的处理逻辑是在Autowired的处理逻辑里做了一层检查,当声明了@Qualifier时,直接过滤掉name不匹配的

    Spring的注入方式大比拼

    Resource

    这个注解的处理逻辑是在CommonAnnotaionBeanPostProcessor中(此类一并处理了其它JSR250的一些注解),它对依赖bean的查找方式与Autowired相同,都是由DefaultListableBeanFactory中的逻辑实现的,所以Qualifier同样适用于Resource,这里就不再贴代码。

    BTW,从高内聚低耦合的原则出发,推荐使用JSR标准注解

    Spring的注入方式大比拼

    欢迎关注,期待与您的交流,让我们携手在通往牛逼的小路上徐徐前行。

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> Spring的注入方式大比拼


     上一篇
    玩转Spring bean的终极利器 玩转Spring bean的终极利器
    前面的篇幅里有提到通过InitializingBean和Disposable等接口可以对bean的初始化和销毁做一些自定义操作,那么有一点要注意,那仅仅是在bean被容器实例化之后的操作,在spring的世界里,要想对实例化这个过程做点什么
    2021-04-05
    下一篇 
    面试中常问到的Spring注入循环依赖 面试中常问到的Spring注入循环依赖
    在Spring注入的机制里,人们常提到的一个问题是循环依赖,那么什么是循环依赖,假设有两个bean,你中有我,我中有你,这样一来,在容器创建bean的时候是如何处理的呢,是鸡生蛋,还是蛋生鸡,这是个问题。 我们先来看两个小例子 A B类
    2021-04-05