如何解决使用注解将 EhCache XML 转换为 Java 类并在 JMX 中注册
在我们的项目中,我们有两个模块:api 和 api-component,每个模块都有一个 cache.xml 文件,该文件引用另一个 ehcache.xml 文件,如下所示:
cache.xml(在两个模块中)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache" />
</bean>
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerfactorybean"
p:config-location="classpath:ehcache.xml" />
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerfactorybean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<bean class="net.sf.ehcache.management.ManagementService"
init-method="init">
<constructor-arg ref="ehcache" />
<constructor-arg ref="mbeanServer" />
<constructor-arg value="true" />
<constructor-arg value="true" />
<constructor-arg value="true" />
<constructor-arg value="true" />
</bean>
</beans>
ehcache.xml(在两个模块中)
<ehcache name="ApiCacheManager">
<diskStore path="java.io.tmpdir"/>
<cache name="myCache" -- Different name in each file
maxElementsInMemory="1000"
eternal="false"
timetoIdleSeconds="500"
timetoLiveSeconds="500"
overflowTodisk="false"
statistics="true"
/>
<defaultCache
maxElementsInMemory="1000"
eternal="true"
overflowTodisk="false"
/>
</ehcache>
为了使用注释将这些 XML 文件转换为 Java 类,我想出了这些配置,同样在两个模块中:ApiCacheConfiguration.java 和 ApiComponentCacheConfiguration.java
import net.sf.ehcache.Cache;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.diskStoreConfiguration;
import net.sf.ehcache.management.ManagementService;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.interceptor.*;
import org.springframework.cache.support.CompositeCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jmx.support.MBeanServerfactorybean;
import java.util.Collections;
@Configuration
@EnableCaching
public class ApiCacheConfiguration extends CachingConfigurerSupport {
@Primary
@Bean
public CacheManager cacheManager() {
CompositeCacheManager compositeCacheManager = new CompositeCacheManager();
compositeCacheManager.setCacheManagers(Collections.singleton(ehCacheManager()));
return compositeCacheManager;
}
@Bean
public EhCacheCacheManager ehCacheManager() {
EhCacheCacheManager cacheManager = new EhCacheCacheManager(ehCacheCacheManager());
ManagementService.registerMBeans(
cacheManager.getCacheManager(),mBeanServer().getobject(),true,true);
return cacheManager;
}
@Bean
public MBeanServerfactorybean mBeanServer() {
MBeanServerfactorybean mBeanServerfactorybean = new MBeanServerfactorybean();
mBeanServerfactorybean.setLocateExistingServerIfPossible(true);
return mBeanServerfactorybean;
}
@Bean
@Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver(cacheManager());
}
@Bean
@Override
public KeyGenerator keyGenerator() {
return new SimpleKeyGenerator();
}
@Bean
@Override
public CacheErrorHandler errorHandler() {
return new SimpleCacheErrorHandler();
}
private net.sf.ehcache.CacheManager ehCacheCacheManager() {
net.sf.ehcache.CacheManager cacheManager = new net.sf.ehcache.CacheManager(ehCacheConfiguration());
cacheManager.setName("ApiCacheManager"); // If name is not set I'm not getting 'InstanceAlreadyExistsException'
cacheManager.addCache(myCache());
return cacheManager;
}
private Cache myCache() {
CacheConfiguration configuration = new CacheConfiguration("myCache",100) // Different name in each file
.eternal(false)
.timetoIdleSeconds(600)
.timetoLiveSeconds(3600)
.overflowTodisk(false)
.statistics(true);
return new Cache(configuration);
}
private net.sf.ehcache.config.Configuration ehCacheConfiguration() {
diskStoreConfiguration diskStoreConfiguration = new diskStoreConfiguration();
diskStoreConfiguration.setPath("java.io.tmpdir");
CacheConfiguration defaultCacheConfiguration = new CacheConfiguration();
defaultCacheConfiguration.maxElementsInMemory(1000);
defaultCacheConfiguration.eternal(true);
defaultCacheConfiguration.overflowTodisk(false);
net.sf.ehcache.config.Configuration configuration = new net.sf.ehcache.config.Configuration();
configuration.setDefaultCacheConfiguration(defaultCacheConfiguration);
configuration.adddiskStore(diskStoreConfiguration);
return configuration;
}
}
一切都和之前的 ehCache.xml 写的差不多,但是,我不知道是怎么回事,正在创建 ApiCacheManager 和 ApiComponentCacheManager 的多个 bean,抛出这些错误:
Caused by: javax.management.InstanceAlreadyExistsException: net.sf.ehcache:type=CacheManager,name=ApiCacheManager
Caused by: javax.management.InstanceAlreadyExistsException: net.sf.ehcache:type=CacheManager,name=ApiComponentCacheManager
如果未设置 CacheManager 名称,则不会出现此错误,但多个 bean 已注册到 JMX:
如何使用我设置的名称仅将我的两个 CacheManager 放入 JMX? CacheManager 的创建有什么问题吗?也许不是创建单例?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。