前面文章中对依赖注入的触发和bean的创建做了学习记录,本文将来记录一下bean的属性注入过程。Bean的属性注入发生在这个类中,这类是用于bean工厂实现的Helper类,职责就是将bean定义对象中包含的值解析为应用于目标bean实例的实际值。
类中的方法包含了对所有注入类型的处理。所以本文主要围绕这个方法展开来说。
resolveValueIfNecessary方法
:给定一个PropertyValue,返回一个value,解析对工厂中其他bean的引用。 value可能是:
RuntimeBeanReference : 在解析到依赖的Bean的时侯,解析器会依据依赖bean的name创建一个RuntimeBeanReference对像,将这个对像放入BeanDefinition的MutablePropertyValues中。
ManagedList:用来保存它所管理的List元素,它可以包含运行时期的bean引用(将被解析为bean对象).
ManagedSet :用来保存它所管理的set值,它可以包含运行时期的bean引用(将被解析为bean对象)
ManagedMap :用来保存它所管理的map值,它可以包含运行时期的bean引用(将被解析为bean对象)
1、方法申明
argName :为其定义的参数的名称
value :要解析的值对象
2、RuntimeBeanReference
当在beanfactory中作为另外一个bean的引用时,作为属性值对象,将在运行时进行解析。 RuntimeBeanReference是在对BeanDefinition进行解析时生成的数据对象。
3、RuntimeBeanNameReference
当在beanfactory中作为另外一个bean名称的引用时,作为属性值对象,将在运行时进行解析。
4、BeanDefinitionHolder
解析BeanDefinitionHolder:包含具有名称和别名的BeanDefinition。BeanDefinitionHolder就是使用名称或者别名来保存BeanDefinition的。
5、BeanDefinition
解析纯粹的BeanDefinition
6、ManagedArray
包含运行时期的bean引用(将被解析为bean对象)
7、ManagedList,ManagedSet,ManagedMap
包含运行时期的bean引用(将被解析为bean对象)
8、ManagedProperties
ManagedProperties表示的是一个spring管理的属性实例,它支持父/子 definition的合并。
9、TypedStringValue
TypedStringValue保存的是一个类型的属性值。
10、作为表达式进行评估
将给定的值作为表达式进行评估。
在完成上述解析之后,已经为我们的依赖注入做好了准备。这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,可以看到,处理的属性也是各式各样的。具体属性的注入是在之前提到的BeanWrapper接口的实现类BeanWrapperImpl的setPropertyValue方法来完成。
setPropertyValue方法
a、方法声明
这个方法是私有的,是BeanWrapperImpl实际处理的方法,其对外也提供了setPropertyValue的其它重载方法来提供服务。
b、PropertyTokenHolder是BeanWrapperImpl的内部类
在setPropertyValue方法中会根据tokens变量是否为null,有两个不同的分支。其中当tokens为null时,则会对属性名进行递归调用分析处理,返回分析处理后的BeanWrapImpl对象nestedBw。如果nestedBw==this,则会设置pv的resolvedTokens属性值,最后将调用nestedBw对象的设置属性值方法设置属性。来具体看看:
c、其中当tokens为null时,即对集合类的域进行注入
1、propValue为null
propValue为null
2、对array进行注入
对array进行注入
2、对list进行注入
对list进行注入
2、对map进行注入
对map进行注入
其中当tokens不为null时,即对非集合类的域进行注入
这里是核心的地方,取得注入属性的set方法,通过反射机制,把对象注入进去。
总结
通过上面的几篇分析我们大概的熟悉了Bean创建和对象依赖注入的一个过程,在这个过程中,spring需要根据Beandefinition中的信息来递归完成依赖注入。并且这些递归的入口都是getBean这个方法。
一个递归是在上下文体系中查找需要的Bean和创建Bean的递归调用;
另一个递归是在依赖注入时通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也触发对依赖Bean的创建和注入。
在对Bean的属性进行依赖注入时解析的过程也是一个递归的过程。这样就可以根据依赖关系,一层一层的完成Bean的创建和注入,直到最后完成当前Bean的创建。
参考
《Spring技术内幕》
https://www.cnblogs.com/davidwang456/p/4213652.html
领取专属 10元无门槛券
私享最新 技术干货