xml方式往bean注入配置信息
配置文件application.properties
person.name=liuben
person.password=123456
value=giao
application.xml
![](https://img.haomeiwen.com/i23353704/8ab74c7535298f86.png)
Person类
![](https://img.haomeiwen.com/i23353704/f6ef7724dd2c266d.png)
这样xml中配置的bean的属性就会被注入配置文件里面对应的值
xml方式源码解析:
首先xml中的bean会在扫描的过程中封装成BeanDefinition对象,property标签会被弄成一个ProprotyValue的集合放在BeanDefinition的ProprotyValues变量中,所以在xml解析完成之后的BeanDefinition的ProprotyValues变量是这样的
![](https://img.haomeiwen.com/i23353704/3d6a041a935847fb.png)
上节PropertySourcesPlaceholderConfigurer这个类收集了environment配置信息和本地配置信息,并把它放在了PropertySourcesPropertyResolver的propertySources属性中
![](https://img.haomeiwen.com/i23353704/717be81c37a92d48.png)
最后创建了一个StringValueResolver对象会调用PropertySourcesPropertyResolver来处理配置信息的替换
![](https://img.haomeiwen.com/i23353704/958c1434fcd0d2a5.png)
接下来就是取出所有的BeanDefinition,看看beanDefinition中的属性中是否有${}表达式,有的话就替换
![](https://img.haomeiwen.com/i23353704/977e392acee35e0e.png)
很多的属性都可以用${}来引用配置信息
ParentName
BeanClassName
FactoryBeanName
FactoryMethodName
Scope
PropertyValues
ConstructorArgumentValues //构造方法参数
![](https://img.haomeiwen.com/i23353704/ed3eaeef9832b829.png)
重点看看属性是如何被替换的
![](https://img.haomeiwen.com/i23353704/1490b47e9aac7aac.png)
需要将${person.name} 替换成配置信息中的值
![](https://img.haomeiwen.com/i23353704/a46e3bc0b499c245.png)
在BeanDefinitionVisitor.resolveValue方法中,String类型的走这
![](https://img.haomeiwen.com/i23353704/02a1ef550ddd1969.png)
最终会调到PropertySourcesPlaceholderConfigurer创建的StringValueResolver匿名对象的实现方法中
![](https://img.haomeiwen.com/i23353704/b4d6c158e0a169f6.png)
![](https://img.haomeiwen.com/i23353704/476aec5352c5e369.png)
这个匿名对象实现的方法又会调用PropertySourcesPropertyResolver来替换值,前面有提到所有的配置信息都在PropertySourcesPropertyResolver.propertySources中,那么接下来的工作就是从这个容器中找到对应的配置信息的key所对应的value
![](https://img.haomeiwen.com/i23353704/04e40333cdea650c.png)
这里在入参时会创建一个PlaceholderResolver的匿名对象,实现的resolvePlaceholder方法将会调用PropertySourcesPropertyResolver.getPropertyAsRawString()
![](https://img.haomeiwen.com/i23353704/b367dcaa655ccc61.png)
![](https://img.haomeiwen.com/i23353704/6c4b468ed3cbf0d4.png)
![](https://img.haomeiwen.com/i23353704/d61f1b962097304e.png)
最后返回了被替换成对应配置信息的值
![](https://img.haomeiwen.com/i23353704/4efdb89314db2c45.png)
这里就会调用前面创建的匿名对象的实现方法,方法体重会调用调用PropertySourcesPropertyResolver.getPropertyAsRawString(),去用key获取对应的配置信息
![](https://img.haomeiwen.com/i23353704/a35d67b45a718a2e.png)
PropertySourcesPropertyResolver.getPropertyAsRawString()
![](https://img.haomeiwen.com/i23353704/051e5f9cb37e90ee.png)
PropertiesPropertySource对象内部有name,和source,source是一个泛型,当前类型为Properties,PropertiesPropertySource需要实现getProperty方法,其实就是从source中获取属性值
![](https://img.haomeiwen.com/i23353704/1e8d7595577b8bfa.png)
最后调到了Properties类的get方法,返回value
获取到替换后的值,重新以k-v的形式往BD的propertyValues里加
![](https://img.haomeiwen.com/i23353704/06fff8b534bcfcd5.png)
对每个beanDefination都这样操作过一遍
处理Bean的别名
![](https://img.haomeiwen.com/i23353704/88bb37acc641a8ac.png)
![](https://img.haomeiwen.com/i23353704/50fe2c8265359ad3.png)
最后将StringValueResolver对象放到BeanFactory的embeddedValueResolvers容器中
注意这个StringValueResolver的resolveStringValue会调用PropertySourcesPropertyResolver的方法来处理配置信息的替换,PropertySourcesPropertyResolver持有了所有的配置信息。 那么后面@Value的解析也将StringValueResolver来完成
![](https://img.haomeiwen.com/i23353704/f1b53b7b4d603a4d.png)
![](https://img.haomeiwen.com/i23353704/fec43146dbfccd45.png)
@Value源码解析:
@Value的解析工作是在Bean实例化后,属性注入的时候从配置文件找出并设置进去的
![](https://img.haomeiwen.com/i23353704/0d1a559e754821b4.png)
![](https://img.haomeiwen.com/i23353704/d823c1f89bf5320d.png)
populateBean方法
![](https://img.haomeiwen.com/i23353704/2d6c727b4b89aa04.png)
![](https://img.haomeiwen.com/i23353704/4b4281e4fba61d49.png)
![](https://img.haomeiwen.com/i23353704/909c3e0dbddf5174.png)
![](https://img.haomeiwen.com/i23353704/fe6274cf5b9ae995.png)
只有string类型的才能@Value注解,才需要处理
![](https://img.haomeiwen.com/i23353704/23b023368fea84ee.png)
又是这个容器,之前PropertySourcesPlaceholderConfigurer的doProcessProperties放进去的StringValueResolver
![](https://img.haomeiwen.com/i23353704/32f79c66127b3916.png)
最后又会回到这个地方解析并注入值,和xml方式获取配置信息是一样的
![](https://img.haomeiwen.com/i23353704/5ded2dffed89470e.png)
找到对应的配置信息之后,反射设置这个属性的值
![](https://img.haomeiwen.com/i23353704/e6b07ce00884f92c.png)
网友评论