我这样做如下:
- 注册一个 NamespaceHandler (与所有 spring.x 文件,处理程序被正确定位和调用)
在命名空间处理程序注册的解析器中,我加载了一个包含 bean 定义的 xml 文件(而不是以编程方式定义它们):
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(parserContext.getRegistry()); reader.loadBeanDefinitions(new ClassPathResource("definitions.xml"));
Definitions.xml 包含一个
<context:property-placeholder location="classpath:.. />
- 调用我的处理程序的 applicationContext.xml 需要传递一个属性(例如
<foo:bar prop="${baz}" />
- 在命名空间处理程序中,我定义了一个内联
PropertySource
并将其注册到环境中,以便我可以动态注册我需要的属性,该属性基于prop
传递的 as 属性。我尝试注册一个 String bean,但解析失败。
属性占位符解析发生在 bean 定义之后,因此发生在我的命名空间处理程序解析器中的代码被调用之后。
然而,这一切都失败了。多次,出于多种原因。他们是这样的:
如果
<context:property-placeholder />
未定义ignore-unresolvable="true"
andorder
,则第一个占位符配置器无法找到第二个所需的属性。当然,这是合乎逻辑的,并且在使用多个占位符配置器时似乎是强制性的因为动态属性是基于传递的
prop
,看起来file://${prop}/foo", which means it is a nested property. You can't configure the behaviour of nested property resolution per configurer, which means even though
ignore-unresolvable`是真的,嵌套的属性没有被忽略,整个事情都失败了。
我找到的解决方案是AbstractEnvironment
在命名空间处理程序的解析器中获取,并设置调用env.setIgnoreUnresolvableNestedPlaceholders(true)
这看起来像一个黑客。所以我的问题是:
- 如何动态注册稍后将被解析的属性?
- 如何配置忽略每个配置器的嵌套属性解析?
- 有没有更好的方法来实现我的需要 - 即通过自定义命名空间包含定义的“捆绑”,并将属性(从文件加载)传递给它们?
PS Spring 改进请求发布:https ://jira.springsource.org/browse/SPR-10654