我正在开发一个Spring webapp,我有一个我作为jar文件包含的库。该库使用Spring注释,它有自己的上下文文件,在我的webapp的contextConfigLocation
上下文参数中引用。该库有自己的属性文件,通过<context:property-placeholder ... />
加载,其值通过@Value
注释在库的代码中使用。
我能够在我的webapp中使用该库,直到我通过相同的机制(即<context:property-placeholder...
)将属性文件添加到我的webapp。突然间,我开始收到一条说明“无法解决占位符”的异常,占位符是我的库代码中引用的第一个占位符。
我花了好几个小时试图解决这个问题,阅读问题,文档,代码,最后遇到了一些示例代码,它正在做我想要做的事情:设置一个Spring托管的库,从外部加载属性文件。显示属性文件加载的片段为我的问题提供了解决方案,但没有解释为什么它有效。在库的应用程序上下文中,我必须像这样引用属性文件:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:my/package/config/app-lib.properties" />
<property name="placeholderPrefix" value="$app-lib{" />
</bean>
我很高兴我的代码再次运行,但我并不完全满意,因为我不明白发生了什么。 This question类似(我在搜索答案时错过了它的重要性)但答案并没有说明为什么使用placeholderPrefix
是必要的。
有人可以解释为什么我的图书馆在我自定义前缀之前无法找到它的属性吗?
答案 0 :(得分:3)
通常,您只能拥有一个PropertyPlaceholderConfigurer,它负责处理所有属性占位符。
由于您使用的库显然已经设置了PropertyPlaceholderConfigurer,因此您的库与库中的库进行了冲突,该库设置为读取库的属性文件,而不是您的应用程序。
通过设置不同的placeholderPrefix,您允许两个PropertyPlaceholderConfigurer实例共存,库的实例处理“普通”属性占位符(默认前缀为“$ {”的实例,并且您的应用程序的实例处理自定义占位符,前缀为“$ app-lib {”。
答案 1 :(得分:2)
添加到@GreyBeardedGeek,如果两个PropertyPlaceHolders有相同的占位符前缀/后缀,那么理论上一个属性值将来自两个占位符,并且两个占位符都可以指向不同的文件。
这没有逻辑意义。这就是为什么每当你添加第二个属性占位符时,你必须使它的前缀和后缀组合独特于任何其他先前定义的属性占位符。