Spring @Autowired 自动装配 ?

以前在网上看过一些关于spring 自动装配的文章,有人说@Autowired就是自动装配,其实这是不正确的,今天我将会以官网文档和源码来说明这个问题。
讲自动装配之前我想先看一下官方文档对自动装配的描述,可以看到,自动装配有四种模式:
在这里插入图片描述
从上图可以看到,默认Mode为no,代表没有自动装配,然后我们再看看AutowireCapableBeanFactory中定义的几个常量,其实就是跟上图中四种模式对应的,但是下图中有5个,只不过第5个AUTOWIRE_AUTODETECT已经被废弃了,所以我们认为只有四种模式即可。
在这里插入图片描述
接着,可以从源码着手讲@Autowired为什么不是自动装配了,上图:
在这里插入图片描述
从上图中可以看到,A依赖了B,然后在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean中断点,并加上条件beanName.equals(“a”),所以只有beanName为a时,才会进入这个断点,断点往下执行后可以看到resolvedAutowireMode=0及beanDefinition中的autowireMode=0,结合上文中提到的四种装配模式和对应的数值,可以发现a的自动装配模式为no,也就是默认没有自动装配,这就是最直接的证据说明@Autowired不是自动装配。

但是,最后控制台打印出b的地址值,说明注入b成功,那么是怎么注入的呢,接着上一幅图,拿到resolvedAutowireMode的值后继续往下执行,如下图:
在这里插入图片描述
从上图中可以看到,spring调用了bean的后置处理器来完成属性注入,默认有6个,最开始bw中的wrappedObject中的b=null,直到beanPostProcessor=AutowiredAnnotationBeanPostProcessor且执行完 if 逻辑,可以看到b已经有值了,这时候已经完成了对属性b的注入,最后直接执行完所有流程,控制台打印出b的地址。
a完成属性b的注入实际上是通过 field.set 方式注入的,具体代码可见:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
在这里插入图片描述
其实,从int resolvedAutowireMode = mbd.getResolvedAutowireMode(); 到调用bean的后置处理器中间还有一段逻辑,如下图:
在这里插入图片描述
这段逻辑对应的就是:当自动装配模式为BY_NAME或BY_TYPE时的属性注入,既然加了@Autowired不是自动装配,那么怎么模拟自动装配呢?如下图:
在这里插入图片描述
从上图可以看出,A中已经没有属性b,只有setB方法,然后自定义了一个MyBeanFactoryPostProcessor来修改a的自动装配模式为2-byType,在执行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean的断点resolvedAutowireMode后,resolvedAutowireMode=2,然后进入了if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) 的逻辑,直接执行完,发现控制台打印出b的地址,说明注入成功,这时候a中已经没有属性b,更不要提@Autowired 了,这说明自动装配其实与@Autowired 无关。

实现自动装配还有另一种方式,就是xml配置,这时候已经不需要MyBeanFactoryPostProcessor了,简单演示一下,如下图:
在这里插入图片描述
从上图可以看出,通过xml配置方式和java配置方式实现的最终效果一致,通过xml配置方式也可以看出,只需要设置autowire = “byType” 就完成自动装配了(当然还有byName和constructor),并不需要像下图一样配置:
在这里插入图片描述
其实,从官网所讲的自动装配的优点中也可以看出,上图示例属于手动装配,如图:
在这里插入图片描述
简言之,假设A中现在新增依赖项C,那么就不需要再去xml中指定C的依赖关系,可以自动满足和注入。

参考文档: https://docs.spring.io/spring/docs/5.2.5.RELEASE/spring-framework-reference/core.html#beans-factory-autowire

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值