spring内幕(八)bean的初始化之populateBean()方法

时间:2024-04-09 08:02:23

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

1.先从beanDefinition中取得设置的property值

2.执行autowireByName方法 (根据bean的名字注入)
或者 autowireByType方法 (根据bean的类型注入)

举例:
byType
spring内幕(八)bean的初始化之populateBean()方法
byname
spring内幕(八)bean的初始化之populateBean()方法

区别就是 byName,bean的id要和需要注入的bean里面的类成员变量名称一致,byType则不需要,但是如果存在两个相同类型,就会报错。

注意!以上是在xml里面对bean进行配置的时候设置的autowire属性 ,不是@Autowire注解

@Autowired是spring的注解,默认使用的是byType的方式向Bean里面注入相应的Bean

因此,如果我们@Autowired 一个接口,那么就会在ioc容器里面找到这个接口的实现类的bean 进行注入,但是如果有两个实现类 ,因为byType就无法确定是哪一个,那就会报错了。

通过@Qualifier注解来指明使用哪一个实现类,实际上是通过byName的方式实现,指定了bean的名字。

autowireByName
先根据beanName 获取到该bean的要注入的属性名称数组
然后遍历属性名称数组 用属性名称挨个去ioc容器中获取bean
放到依赖缓存集合中

autowireByType
根据bean的类型,

最终从
BeanFactoryUtils.beanNamesForTypeIncludingAncestors方法中 获取到需要符合类型的所有bean。

org.springframework.beans.factory.BeanFactoryUtils
#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class<?>, boolean, boolean)
放到依赖缓存集合中

然后在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues方法中

将对应的beanDefinition转换为Bean
(这里会对PropertyValues的属性列表进行一份深拷贝,因为后面会用到将这个属性列表里面的beanDefinition转换为bean)

使用的是BeanDefinitionValueResolver来对beanDefinition进行解析
spring内幕(八)bean的初始化之populateBean()方法

解析一个引用为一个bean 会去容器中找,又会触发getBean
spring内幕(八)bean的初始化之populateBean()方法

除此之外,还有其他类型的解析
spring内幕(八)bean的初始化之populateBean()方法

拿到bean之后,最后调用BeanWrapper的setPropertyValues方法进行注入
不同的属性类型 调用不同的注入方法。
spring内幕(八)bean的初始化之populateBean()方法

最终是获取到注入属性的set方法,通过反射机制,把对象注入进去
spring内幕(八)bean的初始化之populateBean()方法

writeMethodName如下
spring内幕(八)bean的初始化之populateBean()方法

spring内幕(八)bean的初始化之populateBean()方法

因此 xml形式的bean配置 使用了set注入的话 是需要有set方法的。

但是通过注解@Autowire 就不需要set方法,spring会通过属性注入值,对私有属性暴力反射访问 修改权限 直接赋值。
比如说所如下
spring内幕(八)bean的初始化之populateBean()方法