日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SPRING多个占位符配置文件解析源码研究--转

發布時間:2025/4/5 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SPRING多个占位符配置文件解析源码研究--转 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文地址:http://www.cnphp6.com/archives/85639

Spring配置文件:

<context:property-placeholder?location="classpath:/settings.properties"?/> <context:property-placeholder?location="classpath:/conf.properties"/>

settings.properties

redis.masterName=mymaster

conf.properties

home.abroad=1

測試類:

@Component public?class?PropertyPlaceHolderTest?{@Value("${redis.masterName}")String?masterName;@Value("${home.abroad}")int?homeAbroad;public?static?void?main(String[]?args)?{ApplicationContext?ctx?=?new?ClassPathXmlApplicationContext("classpath:applicationContext-test.xml");PropertyPlaceHolderTest?bean?=?ctx.getBean(PropertyPlaceHolderTest.class);System.out.println(ToStringBuilder.reflectionToString(bean));} }

執行上述測試類 報錯:

Caused?by:?java.lang.IllegalArgumentException:?Could?not?resolve?placeholder?'home.abroad'?in?string?value?[${home.abroad}]at?org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:173)at?org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:125)at?org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:151)at?org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:142)at?org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:169)at?org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:748)at?org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:745)at?org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)at?org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)...?15?more

?

為什么只能解析出第一個property-placeholder配置中的key?第二個property-placeholder配置文件中的key是被忽略了嗎?

但明明日志顯示兩個配置文件均被成功解析了啊。

INFO??org.springframework.context.support.PropertySourcesPlaceholderConfigurer??Loading?properties?file?from?class?path?resource?[settings.properties] INFO??org.springframework.context.support.PropertySourcesPlaceholderConfigurer??Loading?properties?file?from?class?path?resource?[conf.properties]

那到底是什么原因呢?只有分析源代碼了。發現一旦解析配置文件后會將其封裝到一個PropertySourcesPropertyResolver對象中,如下所示:

//所屬類:PropertySourcesPlaceholderConfigurer @Override public?void?postProcessBeanFactory(ConfigurableListableBeanFactory?beanFactory)?throws?BeansException?{????????//......???this.processProperties(beanFactory,?new?PropertySourcesPropertyResolver(this.propertySources)); }

再創建一個StringValueResolver對象,實際使用上面的PropertySourcesPropertyResolver對象來解析占位符中的字符串。

//所屬類:PropertySourcesPlaceholderConfigurer protected?void?processProperties(ConfigurableListableBeanFactory?beanFactoryToProcess,final?ConfigurablePropertyResolver?propertyResolver)?throws?BeansException?{//......StringValueResolver?valueResolver?=?new?StringValueResolver()?{public?String?resolveStringValue(String?strVal)?{String?resolved?=?ignoreUnresolvablePlaceholders??propertyResolver.resolvePlaceholders(strVal)?:propertyResolver.resolveRequiredPlaceholders(strVal);return?(resolved.equals(nullValue)???null?:?resolved);}};doProcessProperties(beanFactoryToProcess,?valueResolver);}

最后將此StringValueResolver對象放入到一個List中,

//所屬類:AbstractBeanFactory public?void?addEmbeddedValueResolver(StringValueResolver?valueResolver)?{Assert.notNull(valueResolver,?"StringValueResolver?must?not?be?null");this.embeddedValueResolvers.add(valueResolver);}

當自動注入@Value標注的字段時,

DEBUG?org.springframework.beans.factory.annotation.InjectionMetadata??Processing?injected?method?of?bean?'propertyPlaceHolderTest':?AutowiredFieldElement?for?int?com.tcl.test.PropertyPlaceHolderTest.homeAbroad

需要解析@Value中的占位符中的內容了,涉及到源碼是:

//所屬類:AbstractBeanFactory public?String?resolveEmbeddedValue(String?value)?{String?result?=?value;for?(StringValueResolver?resolver?:?this.embeddedValueResolvers)?{result?=?resolver.resolveStringValue(result);}return?result;}

從之前描述可知this.embeddedValueResolvers中有兩個valueResolver對象(分別對應兩個context:property-placeholder元素),于是先取出第一個valueResolver(對應settings.properties)來解析${home.abroad},而它是配置在conf.poperties中的,肯定解析不到,于是就報錯了,見源代碼:

//所屬的類與方法:PropertyPlaceholderHelper.parseStringValue if?(propVal?!=?null)?{//...... } else?if?(this.ignoreUnresolvablePlaceholders)?{//?Proceed?with?unprocessed?value.startIndex?=?buf.indexOf(this.placeholderPrefix,?endIndex?+?this.placeholderSuffix.length()); } else?{throw?new?IllegalArgumentException("Could?not?resolve?placeholder?'"?+placeholder?+?"'"?+?"?in?string?value?["?+?strVal?+?"]"); }

?

但明明才遍歷了List中第一個valueResolver對象呢,后面的那個可以成功解析啊。錯誤拋的也太急了點吧。

Spring肯定也考慮了這一點,從上面的源代碼也可以看出,只要設置了ignoreUnresolvablePlaceholders為true的話,就不會走最后的else分支了。

修改Spring配置,顯式指定第一個context:property-placeholder元素ignore-unresolvable屬性為true,如下所示:

<context:property-placeholder?location="classpath:/settings.properties"?ignore-unresolvable="true"/> <context:property-placeholder?location="classpath:/conf.properties"/>

這時就不會報錯了,${home.abroad}也能被成功解析了。見輸出:

com.tcl.test.PropertyPlaceHolderTest@2f949a6b[masterName=mymaster,homeAbroad=1]

當然正常情況下沒必要配置成兩個或多個context:property-placeholder,完全可以用一個context:property-placeholder來指定多個配置文件,如下所示:

<context:property-placeholder?location="classpath:/settings.properties,/conf.properties"?/>

轉載于:https://www.cnblogs.com/davidwang456/p/5735452.html

總結

以上是生活随笔為你收集整理的SPRING多个占位符配置文件解析源码研究--转的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。