7

我有一个带有这个的 spring 上下文 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

4 回答 4

12

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

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

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

换句话说,如果您使用EhCacheFactoryBean引用尚未在 中定义的命名缓存cacheConfig.xml,那么 Spring 将创建并配置一个新的缓存实例并将其注册CacheManager到运行时。这包括指定类似的内容maxElementsInMemory,并且因为这将在 Spring bean 定义文件中指定,所以您将获得对属性解析器的完全支持:

<context:property-placeholder location="classpath:cacheConfig.properties"/>

<bean id="myCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
    <property name="cacheManager" ref="cacheManager"/>
    <property name="maxElementsInMemory" value="${cache.maxMemoryElements}"/>
</bean>

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="shared" value="false"/>
    <property name="configLocation" value="classpath:cacheConfig.xml"/>
</bean>
于 2009-10-07T22:37:07.013 回答
3

这不是 PropertyPlaceholderConfigurer 的工作方式。它可用于替换context 中的值,但不能用于替换任意外部文件中的值。并且cacheConfig.xml是一个外部文件 - 它只是由 Spring 传递给 EH Cache。

于 2009-10-07T18:45:44.563 回答
2

For anyone who needs to modify the diskstore path which cannot be set as the ehcache javadoc states that the diskstore parameter is ignored, you could create your own implementation of a EhCacheManagerFactoryBean, which allows you to inject the diskstore path; you basically need to intercept the creation of the CacheManager and modify the configuration passed along using your diskstore property, e.g.:

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;
}

The Spring config then looks like this:

<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>
于 2011-05-19T14:15:23.247 回答
2

如果您使用的是 Maven 或 Ant,两者都提供了对资源文件中的标记进行过滤的能力。

对于 Maven,您可以执行类似的操作

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

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

 cache.maxMemoryElements = 200

Maven 中的资源过滤:权威指南

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

于 2009-10-07T19:13:15.487 回答