我有一个带有此
的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".
提前致谢...
答案 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>