2

在我们的 Spring 配置的一个领域中,我们正在使用:

应用上下文.xml

<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" lazy-init="true">
    <property name="configLocation" value="classpath:ehcache.xml"/>
</bean>

但是,ehcache.xml 不是标准的 spring bean 配置文件,而是包含 ${ehcache.providerURL},我们希望根据我们在其他地方使用 PropertyPlaceHolderConfigurer 配置的内容来替换它:

ehcache.xml

<cacheManagerPeerProviderFactory
   ...
   providerURL=${ehcache.providerURL}
   ...
</cacheManagerPeerProviderFactory>

我可以使用 Maven/profile/filter 组合,但这会创建一个特定于它正在构建的环境的构建。我真正想做的是在运行时预处理 ehcache.xml,根据 PropertyPlaceHolderConfigurer 读取的属性执行替换,然后将结果传递给 EhCacheManagerBean。

此时,我正在考虑以某种方式复制 @Value 注释背后的功能,因为它可以替换“bla bla bla ${property} bla bla bla”,除非我需要在从磁盘读取文件后执行此操作。

关于如何解决这个问题的任何想法?

谢谢。-AP_

4

3 回答 3

7

要直接操作字符串,您可以使用 org.springframework.util.PropertyPlaceholderHelper

String template = "Key : ${key} value: ${value} "
PropertyPlaceholderHelper h = new PropertyPlaceholderHelper("${","}");
Properties p = new Properties(); 
p.setProperty("key","mykey");
p.setProperty("value","myvalue");
String out = h.replacePlaceholders(template,p);

它用相应的属性值替换模板中的值。

于 2012-04-06T20:44:13.840 回答
3

经过一番搜索,这是我想出的精髓。我将它打包成一个接受资源的工厂,并在将所有行替换为 ${propertyPlaceHolder} 与持有者的实际值后转换它。

    final ConfigurableListableBeanFactory
        factory =
            ((ConfigurableApplicationContext) applicationContext).getBeanFactory();

    String line = null;
    while ((line = reader.readLine()) != null) {
        try {
            final String
                result = factory.resolveEmbeddedValue(line);
            writer.println(result);
        }
        catch (final Exception e) {
            log.error("Exception received while processing: " + line, e);
            throw e;
        }
    }

这个解决方案的好处是它使用了与 Spring 用于解析 @Value("${fooBar}") 注释相同的工具。这意味着您可以使用 SpEL 以及 Spring 通常在 @Value 注释中接受的任何其他内容。它还与 PropertyPlaceholderConfigurer 集成。

希望这可以帮助某人。

-AP_

于 2012-04-06T08:02:22.437 回答
1

PropertyPlaceholderConfigurer 用于替换 Spring 配置文件中的属性。它不会替换外部文件中的属性。PropertyPlaceholderConfigurer 无法解决您的问题。

在创建 CacheManager 之前,您可以覆盖org.springframework.cache.ehcache.EhCacheManagerFactoryBean.afterPropertiesSet()方法并使用 xml 做任何您想做的事情。您知道它有多干净 :)

于 2012-04-06T00:57:07.297 回答