SpringBoot加载配置文件(@PropertySource@importSource@Value)
2020-12-13 03:06
标签:描述 tle stp beans actor www 取值 https cat 情景描述 最近新搭建了一个项目,从Spring迁到了Springboot,为了兼容Spring加载配置文件的风格,所以还想把PropertyPlaceholderConfigurer放在.xml文件里面,然后通过@importSource来加载.xml文件将配置加载到spring环境中,通过@value或者PropertyUtil来引入对应配置的值。于是发现了以下问题,并根据这些问题进行了问题拓展。 问题描述 1.在.xml引入PropertyPlaceholderConfigurer时,若项目中存在@PropertySource注解,@ConfigurationProperties可以正常加载PropertySource中的配置(启动时发现Bean正常),但是@Value会在启动时报错解析不了占位符;若@ConfigurationProperties加载的是.xml中配置文件的值,则也为空。 2.在使用PropertyUtil(由.xml加载配置)时发现,在通过.xml加载配置的这个方法上,public static 变量在@Configuration的配置类通过PropertyUtil获取配置值时PropertyUtil还未加载(值为null),在其他@Component(包括@Controller)中是可以正常获取到值(说明已经加载)。 解决方案&原理分析 问题1: 其中@PropertySource注解管理的所有配置文件相当于一个PropertyPlaceholderConfigurer,只不过是Springboot自己管理的,而.xml中的PropertyPlaceholderConfigurer又是一个,这就会出现多个PropertyPlaceholderConfigurer的问题(目测是由于先加载了@ImportSource中.xml的PropertyPlaceholderConfigurer导致该问题),多PropertyPlaceholderConfigurer问题原因如下: 在spring bean装配时,一个PropertyPlaceholderConfigurer就是一个后置处理器BeanFactoryPostProcessor。在装配完PropertyPlaceholderConfigurer之后,就会触发org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(Collection extends BeanFactoryPostProcessor>, ConfigurableListableBeanFactory)方法,代码如下: 在每调用完一个BeanFactoryPostProcessor之后,就会去解析所有的bean中引用properties的占位符,这时就会出现占位符不能解析的问题(不能解析的占位在后面的BeanFactoryPostProcessor中,也就是PropertyPlaceholderConfigurer实例)。 而在使用@Value时,由于使用了占位符,而.xml中的PropertyPlaceholderConfigurer先加载解析占位符但是该配置未存在,所以会报错占位符解析失败。 而使用@ConfigurationProperties时,并没有使用占位符,所以如果是在@PropertySource中的配置可以正常加载 但是我个人理解@ConfigurationProperties加载配置是用的@PropertySource的PropertyPlaceholderConfigurer,所以如果配置不是用@PropertySource加载,则加载结果为null(建议配套使用) 解决方法: 加上上面的一行,表示可以忽略未解析到的占位符。这样就不会报错。 问题2: 如果对我上面的分析存在异议欢迎讨论啊,希望相互提高。 转载请注明:https://www.cnblogs.com/fnlingnzb-learner/p/11067338.html SpringBoot加载配置文件(@PropertySource@importSource@Value) 标签:描述 tle stp beans actor www 取值 https cat 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/11067338.html/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private void invokeBeanFactoryPostProcessors(
Collection extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
文章标题:SpringBoot加载配置文件(@PropertySource@importSource@Value)
文章链接:http://soscw.com/essay/26941.html