Ehcache正在注册两次bean



我不知道这是否是正常行为,但当我启动Spring服务器时,我会检查缓存是否正常工作,此时Ehcache会通知我何时正确注册了模型:

2020-11-06 21: 38: 23.253 INFO 32643 --- [main] org.ehcache.jsr107.Eh107CacheManager: Registering Ehcache MBean javax.cache: type = CacheStatistics, CacheManager = urn.X-ehcache.jsr107-default-config , Cache = com.github.apolalca.spring.boot.model.bean.User

我注意到Ehcache为我注册了两次模型:

2020-11-06 21: 38: 22.860 INFO 32643 --- [main] c.g.a.s.b.c.MultiCacheManagerConfig: Created cache memory with size (2)
2020-11-06 21: 38: 22.860 INFO 32643 --- [main] c.g.a.s.b.c.MultiCacheManagerConfig: Created cache disk with size (1)
2020-11-06 21: 38: 22.860 INFO 32643 --- [main] c.g.a.s.b.c.MultiCacheManagerConfig: Created cache with size (3)
2020-11-06 21: 38: 23.054 INFO 32643 --- [main] org.ehcache.core.EhcacheManager: Cache 'com.github.apolalca.spring.boot.model.bean.User' created in EhcacheManager.
2020-11-06 21: 38: 23.056 INFO 32643 --- [main] org.ehcache.core.EhcacheManager: Cache 'com.github.apolalca.spring.boot.repository.UserRepository.findByUsername' created in EhcacheManager.
2020-11-06 21: 38: 23.140 INFO 32643 --- [main] org.ehcache.core.EhcacheManager: Cache 'com.github.apolalca.spring.boot.model.bean.Blacklist' created in EhcacheManager.
2020-11-06 21: 38: 23.253 INFO 32643 --- [main] org.ehcache.jsr107.Eh107CacheManager: Registering Ehcache MBean javax.cache: type = CacheStatistics, CacheManager = urn.X-ehcache.jsr107-default-config , Cache = com.github.apolalca.spring.boot.model.bean.User
2020-11-06 21: 38: 23.255 INFO 32643 --- [main] org.ehcache.jsr107.Eh107CacheManager: Registering Ehcache MBean javax.cache: type = CacheStatistics, CacheManager = urn.X-ehcache.jsr107-default-config , Cache = com.github.apolalca.spring.boot.repository.UserRepository.findByUsername
2020-11-06 21: 38: 23.255 INFO 32643 --- [main] org.ehcache.jsr107.Eh107CacheManager: Registering Ehcache MBean javax.cache: type = CacheStatistics, CacheManager = urn.X-ehcache.jsr107-default-config , Cache = com.github.apolalca.spring.boot.model.bean.Blacklist
2020-11-06 21: 38: 23.259 INFO 32643 --- [main] org.ehcache.jsr107.Eh107CacheManager: Registering Ehcache MBean javax.cache: type = CacheStatistics, CacheManager = urn.X-ehcache.jsr107-default-config , Cache = com.github.apolalca.spring.boot.model.bean.User
2020-11-06 21: 38: 23.260 INFO 32643 --- [main] org.ehcache.jsr107.Eh107CacheManager: Registering Ehcache MBean javax.cache: type = CacheStatistics, CacheManager = urn.X-ehcache.jsr107-default-config , Cache = com.github.apolalca.spring.boot.repository.UserRepository.findByUsername
2020-11-06 21: 38: 23.260 INFO 32643 --- [main] org.ehcache.jsr107.Eh107CacheManager: Registering Ehcache MBean javax.cache: type = CacheStatistics, CacheManager = urn.X-ehcache.jsr107-default-config , Cache = com.github.apolalca.spring.boot.model.bean.Blacklist

我创建了一个监听器,当我们创建或修改用户时会跳转(例如(,这个监听器确实注册了一个创建,但从Eh107CacheManager中我看到它注册了两次,为什么会发生这种情况?

缓存有两种配置(这是我的第一种配置,所以很确定如果是故障,那是我的错(,我正在创建两种类型的配置,一种是用户模块的内存配置,另一种是黑名单的持久类型配置(保存到磁盘((例如(

@Configuration
@EnableCaching
public class MultiCacheManagerConfig extends CachingConfigurerSupport {
private static final Logger LOG = LoggerFactory.getLogger(MultiCacheManagerConfig.class);
@Bean
public Blacklist blacklistBean() {
return new Blacklist();
}
@Bean
public org.springframework.cache.CacheManager cacheManager() {
//TODO: In case Multi Cluster -> Create createInMultiClusterCacheManager()
return new JCacheCacheManager(createInMemoryCacheManager());
}
private CacheManager getCacheManager(EhcacheCachingProvider provider, DefaultConfiguration configuration) {
return provider.getCacheManager(provider.getDefaultURI(), configuration);
}
private ClassLoader getClassLoader() {
return this.getClass().getClassLoader();
}
private CacheManager createInMemoryCacheManager() {
long cacheSize = 100;
long ttl = 200;
CacheEventListenerConfigurationBuilder cacheEventListenerConfiguration = CacheEventListenerConfigurationBuilder
.newEventListenerConfiguration(new CustomCacheEventLogger(), EventType.CREATED, EventType.UPDATED, EventType.EVICTED)
.unordered().asynchronous();
org.ehcache.config.CacheConfiguration<Object, Object> cacheConfiguration = CacheConfigurationBuilder
.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder
.heap(cacheSize))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(ttl)))
.withService(cacheEventListenerConfiguration)
.build();
org.ehcache.config.CacheConfiguration<Object, Object> cacheConfigurationDisk = CacheConfigurationBuilder
.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder
.heap(cacheSize)
.disk(20, MemoryUnit.MB, true))
.withService(cacheEventListenerConfiguration)
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(ttl)))
.build();
Map<String, CacheConfiguration<?, ?>> caches = createCacheConfigurations(cacheConfiguration);
LOG.info("Created cache memory with size({})", caches.size());
Map<String, CacheConfiguration<?, ?>> cachesDisk = createCacheConfigurationsDisk(cacheConfigurationDisk);
LOG.info("Created cache disk with size({})", cachesDisk.size());
caches.putAll(cachesDisk);
LOG.info("Created cache with size({})", caches.size());
EhcacheCachingProvider provider = getCachingProvider();
DefaultConfiguration configuration = new DefaultConfiguration(caches, getClassLoader(),
new DefaultPersistenceConfiguration(new File(
"{folder}/persistence",
"myUserData"
))
);
return getCacheManager(provider, configuration);
}

private Map<String, org.ehcache.config.CacheConfiguration<?, ?>> createCacheConfigurations(org.ehcache.config.CacheConfiguration<Object, Object> cacheConfiguration) {
Map<String, org.ehcache.config.CacheConfiguration<?, ?>> caches = new HashMap<>();
caches.put(com.github.apolalca.spring.boot.model.bean.User.class.getName(), cacheConfiguration);
caches.put(UserRepository.USERS_BY_LOGIN_CACHE, cacheConfiguration);
return caches;
}
private Map<String, org.ehcache.config.CacheConfiguration<?, ?>> createCacheConfigurationsDisk(org.ehcache.config.CacheConfiguration<Object, Object> cacheConfiguration) {
Map<String, org.ehcache.config.CacheConfiguration<?, ?>> caches = new HashMap<>();
caches.put(com.github.apolalca.spring.boot.model.bean.Blacklist.class.getName(), cacheConfiguration);
return caches;
}
private EhcacheCachingProvider getCachingProvider() {
return (EhcacheCachingProvider) Caching.getCachingProvider();
}
}

顺便说一下,我正在使用ehcache3和spring5大家好,非常感谢!

UPDATE:这个问题应该在(即将发布的(3.9.7版本中解决,如下所述。更新您的ehcache版本或跟踪版本发布,以便修复问题。


经过一些调查,这似乎是因为以下错误:CacheConfiguration和CacheStatistics MBean被一次又一次地注册

实际情况是,我们希望使用Spring和EhCache 3的组合。

不幸的是,目前春季EhCache 3没有可用的org.springframework.cache.CacheManager(仅适用于v2,即org.springframework.cache.ehcache.EhCacheCacheManager(,因此我们不得不重新使用JCacheCacheManager

JCacheCacheManager也必须在内部初始化其缓存(这些是代理缓存(,这是通过继承自InitializingBeanafterPropertiesSet()方法完成的。在调用此afterPropertiesSet()时,经过一些间接处理后,将调用loadCaches()方法,其中出现以下代码片段:

for (String cacheName : cacheManager.getCacheNames()) {
javax.cache.Cache<Object, Object> jcache = cacheManager.getCache(cacheName);
caches.add(new JCacheCache(jcache, isAllowNullValues()));
}

相关部分基本上是这样的:cacheManager.getCacheNames()

从错误报告中可以看出,这种方法错误地不尊重无副作用原则,并重新初始化缓存。

TLDR:这是EHCache v3中的一个已知错误,并且已经存在一个问题。也许有一天我们会看到一个解决方案。我也提到这个答复,对这个问题发表了评论。

最新更新