Spring context属性占位符ehcache配置

时间:2009-10-07 18:37:08

标签: java spring ehcache

我有一个带有此

的spring context xml文件
<context:property-placeholder location="classpath:cacheConfig.properties"/>

<bean id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="cacheManagerName" value="cacheName"/>
    <property name="shared" value="false"/>
    <property name="configLocation" value="classpath:cacheConfig.xml"/>
</bean>

目标是允许客户编辑属性文件,例如

cache.maxMemoryElements="2000"

然后在实际的cacheConfig.xml文件中有这个

<cache name="someCacheName"
   maxElementsInMemory="${cache.maxMemoryElements}" ... />

因此我们不希望客户更改的项目不会公开。当然,上述细节仅部分详细,不起作用。目前我在日志文件中看到了这个

Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Error configuring from input stream. Initial cause was null:149: Could not set attribute "maxElementsInMemory".

提前致谢...

4 个答案:

答案 0 :(得分:12)

您的示例使用EhCacheManagerFactoryBean公开对CacheManager的引用,并在外部cacheConfig.xml文件中定义了缓存。正如@ ChssPly76指出的那样,Spring的属性解析器只能在Spring自己的bean定义文件中运行。

但是,您不必在外部文件中定义单个缓存,您可以使用EhCacheFactoryBean在Spring bean定义文件中定义它们:

  

创建命名的FactoryBean   EHCache缓存实例......如果   指定的命名缓存不是   在缓存配置中配置   描述符,这个FactoryBean会   用。构造一个Cache的实例   提供的名称和指定的名称   缓存属性并将其添加到   CacheManager供以后检索。

换句话说,如果使用EhCacheFactoryBean来引用尚未在cacheConfig.xml中定义的命名高速缓存,则Spring将创建并配置新的高速缓存实例并将其注册到{ {1}}在运行时。这包括指定CacheManager之类的东西,因为这将在Spring bean定义文件中指定,所以你完全支持属性解析器:

maxElementsInMemory

答案 1 :(得分:3)

这不是PropertyPlaceholderConfigurer的工作原理。它可用于替换上下文中的值 ,但不能替换为任意外部文件中的值。 cacheConfig.xml是一个外部文件 - 它只是被Spring传递给EH Cache。

答案 2 :(得分:2)

如果您使用的是Maven或Ant,则两者都可以在资源文件中过滤令牌。

对于Maven,你可以做类似

的事情
<cache name="someCacheName"
  maxElementsInMemory="${cache.maxMemoryElements}" ... />

在过滤器文件中,或在POM本身中,有

 cache.maxMemoryElements = 200

Resource Filtering in Maven: The Definitive Guide

使用Ant,您可以使用FilterSets<copy>任务执行此操作。

答案 3 :(得分:2)

对于任何需要修改无法设置的磁盘库路径的人,ehcache javadoc声明忽略了diskstore参数,您可以创建自己的EhCacheManagerFactoryBean实现,它允许您注入diskstore路径;你基本上需要拦截CacheManager的创建并修改使用你的diskstore属性传递的配置,例如:

private String diskStorePath;

...getter/setter


public void afterPropertiesSet() throws IOException, CacheException {
    if (this.shared) {
        // Shared CacheManager singleton at the VM level.
        if (this.configLocation != null) {
            this.cacheManager = CacheManager.create(this.createConfig());
        }
        else {
            this.cacheManager = CacheManager.create();
        }
    }
    else {
        // Independent CacheManager instance (the default).
        if (this.configLocation != null) {
            this.cacheManager = new CacheManager(this.createConfig());
        }
        else {
            this.cacheManager = new CacheManager();
        }
    }
    if (this.cacheManagerName != null) {
        this.cacheManager.setName(this.cacheManagerName);
    }
}

private Configuration createConfig() throws CacheException, IOException {
    Configuration config = ConfigurationFactory.parseConfiguration(this.configLocation.getInputStream());

    DiskStoreConfiguration diskStoreConfiguration = config.getDiskStoreConfiguration();
    if (diskStoreConfiguration == null) {
        DiskStoreConfiguration diskStoreConfigurationParameter = new DiskStoreConfiguration();
        diskStoreConfigurationParameter.setPath(getDiskStorePath());
        config.addDiskStore(diskStoreConfigurationParameter);
    } else {
        diskStoreConfiguration.setPath(getDiskStorePath());
    }

    return config;
}

Spring配置看起来像这样:

<bean id="cacheManager" class="com.yourcompany.package.MyEhCacheManagerFactoryBean" depends-on="placeholderConfig">
    <property name="diskStorePath" value="${diskstore.path}"/>
    <property name="configLocation" value="classpath:ehcache.xml" />
</bean>