我有一个BeanDefinitionDecorator,它修改了用户在bean上设置的属性。它工作正常;除非bean使用占位符。我试图找到一个策略来修改这些值,同时仍然可以在运行时访问原始值。 XML中的示例:
<bean id="bean">
<property name="jdbcUrl" value="${jdbc.url}" />
<d:spyDecorator />
</bean>
我知道用户将jdbcUrl属性写为“jdbc:myDatabase”。我想要做的是将其属性更改为“jdbc:spy:myDatabase”。如果他们只使用字符串文字作为属性值,这很容易,但如果他们使用属性占位符,我不知道如何更改值 - 因为我需要原始值才能提供新值。它们的关键是保持财产重写对用户透明。
对此有什么可行的解决方案吗?
答案 0 :(得分:2)
我认为您的命名空间处理程序可以注册BeanFactoryPostProcessor
(使用Orderer
实现order = Integer.MAX_VALUE
是应用的最后一个后处理程序。然后你的BeanDefinitionDecorator
将注册正在装饰的bean以便用该后处理器进行处理(以某种方式在后处理器中实现),后处理器将对该bean应用实际的属性修改。
答案 1 :(得分:1)
您可以使用PropertyPlaceholderConfigurer
替换bean属性,别名和其他位置中占位符的属性值。请注意,替换发生在加载bean定义之后,因此此机制不适用于<import>
元素
例如:
...
<bean id="ppc"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:build.properties</value>
<value>classpath:default-emmet-substitution.properties</value>
<value>classpath:default-danno-substitution.properties</value>
<value>classpath:default-dannotate-substitution.properties</value>
<value>classpath:substitution.properties</value>
</list>
</property>
</bean>
...
有关更多信息,请参阅Spring Framework文档的this section。
编辑 - 我想您的评论已经熟悉了占位符替换的工作方式,并且正在使用PropertyPlaceholderConfigurer
进行替换。所以现在你需要在这些策略或某种组合之间做出选择:
在自定义BeanDefinitionDecorator
中自行替换占位符。这可行,但你要复制很多代码。
让自定义BeanDefinitionDecorator
将占位符名称修改为将引入不同值的不同名称;例如"${jdbc.url}"
变为"${spy.jdbc.url}"
。
扩展PropertyPlaceholderConfigurer
类以修改替换属性值;即覆盖convertProperty
或convertProperties
。这有一个潜在的问题,即所有占位符都将获得修改后的值...而不仅仅是您装饰过的bean中的值。
根据上下文创建一个新的PropertyResourceConfigurer
类来替换不同的属性值。从本质上讲,processProperties
需要像PropertyPlaceholderConfigurer
中的方法一样工作,但如果它看到bean属性或任何告诉它做“间谍”替换的事情,那就做一些不同的事情。
2)和3)的组合看起来最有希望。