学习自定义标签的实现,可以知道<context:property-placeholder/>标签由继承NamespaceHandlerSupport的ContextNamespaceHandler注册PropertyPlaceholderBeanDefinitionParser后进行解析,触发流程详见here,最终创建一个PropertyPlaceholderConfigurer类型的BeanDefinition。
PropertyPlaceholderBeanDefinitionParser的parse方法在(祖父?)抽象类AbstractBeanDefinitionParser中
parse会调用parseInternal方法创建一个AbstractBeanDefinition
它的beanClass由子类提供,部分属性也由子类进行填充
那么剩下的问题则是,我有了beanDefinition,我何时注册实现这个beanfinition从而实现占位符的作用。一开始走了很多弯路,发现等到容器ApplicationContext准备注册具体的beanDefinition时( 即finishBeanFactoryInitialization方法),beanFactory的beanDefinitionMap中的具体bean的propertyValues的具体属性已经被替换了。
替换前
替换后
所以可以判断出,注册前就已经处理好beanDefinition中的属性值了。但问题是具体处理是在在哪个方法。。。
这时网上的一段话给我很大启发。。
PropertyPlaceholderConfigurer是BeanFactoryPostProcessor接口的实现
所以具体处理肯定在invokeBeanFactoryPostProcessors方法中。而他又实现了PriorityOrdered接口。
invokeBeanFactoryPostProcessors方法实际上就是通过postProcessors对beanFactory的beanDefinition进行后处理。
这边对应的是PropertyResourceConfigurer的postProcessBeanFactory方法,里面大致分为两部分,首先从properties文件中拿出所有的key-value类型的值(这边就忽略不跟进了),然后通过processProperties方法 对beanFactory的beanDefinition进行处理。
干事正事do开头
这边就是拿到beanFactory的beanDefinitionNames,遍历拿到对应的beanDefinition,然后进行处理
实际上从方法名就可以看出来那比对了哪些属性替换了哪些。跟到这边差不多可以了
end...