spring - 除非调用 cachemanager.getCacheNames() 否则无法从 cachemanager 获取缓存
问题描述
我的应用程序使用 Spring 4.3.x、EhCache 3.6 和 javax Cache 1.1.0。以下是我在应用程序中配置 javax CacheManager 的方式:
<bean id="jCacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
<property name="cacheManager" ref="appCacheManagerFactoryBean" />
</bean>
<bean id="appCacheManagerFactoryBean" class="com.example.AppCacheManagerFactoryBean"/>
AppCacheManagerFactoryBean(它只是 JCacheManagerFactoryBean 的定制版本)帮助我为我的应用程序配置一个全局持久性目录。这是它的外观:
public class AppCacheManagerFactoryBean implements FactoryBean<CacheManager>, InitializingBean,
DisposableBean {
@Value("${cache.persistenceDir}")
private String persistenceDir;
private CacheManager cacheManager;
@Override
public void afterPropertiesSet() {
this.cacheManager = buildCacheManager();
}
private CacheManager buildCacheManager()
{
EhcacheCachingProvider cachingProvider = (EhcacheCachingProvider) Caching.getCachingProvider();
DefaultConfiguration defaultConfiguration = new DefaultConfiguration(cachingProvider.getDefaultClassLoader(),
new DefaultPersistenceConfiguration(new File(persistenceDir)));
return cachingProvider.getCacheManager(cachingProvider.getDefaultURI(), defaultConfiguration);
}
@Override
public CacheManager getObject() {
return this.cacheManager;
}
@Override
public Class<?> getObjectType() {
return (this.cacheManager != null ? this.cacheManager.getClass() : CacheManager.class);
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void destroy() {
this.cacheManager.close();
}
}
这是我定义缓存的方式。我使用 Ehcache API 来创建我的缓存,因为我的缓存需要的某些功能无法通过 JCache API 获得。
EhcacheManager ehcacheManager = jCacheCacheManager.getCacheManager().unwrap(EhcacheManager.class);
ehcacheManager.createCache("foo", CacheConfigurationBuilder.newCacheConfigurationBuilder(
String.class, Foo.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(1)
.offheap(1, MemoryUnit.GB)
.disk(5, MemoryUnit.GB)
));
当我尝试从应用程序的其他地方的 CacheManager 检索缓存时,会引发空指针异常。
Caching.getCachingProvider().getCacheManager().getCache("foo");
但是,如果我在 CacheManager 中调用 getCacheNames() 方法后检索缓存,则可以正常获取缓存。
Caching.getCachingProvider().getCacheManager().getCacheNames();
Caching.getCachingProvider().getCacheManager().getCache("foo");
我错过了什么?请帮我。
解决方案
我的第一个问题是:“为什么不使用 Spring-cache 的内置支持?” 它不需要这样做。会JCacheCacheManager
照顾好一切。
那么,你的问题是缓存是直接在Ehcache中创建的,没有经过JSR107层。调用getCacheNames()
会导致刷新 JSR107 中的缓存列表以使其工作。但是,我不确定这种全局行为是否有意。但这就是它的工作方式。
解决方案是通过 JSR107 层按预期创建缓存。看起来像这样
CacheManager cacheManager = jcacheCacheManager.getCacheManager();
cacheManager.createCache("foo",
Eh107Configuration.fromEhcacheCacheConfiguration(
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Foo.class, ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(1)
.offheap(1, MemoryUnit.GB)
.disk(5, MemoryUnit.GB))
.build()));
推荐阅读
- python - UTC 中的 Python os.path.getmtime 为什么
- reactjs - Play 中的 CORS 过滤器不明确
- apache-spark - Spark 应用程序以状态 143 退出
- php - 为什么我只从视图中获取第一行值到 Laravel 中的控制器?
- google-cloud-platform - 我们可以使用谷歌云功能将文件从一个项目复制到另一个项目吗
- c++ - free():在 tcache 2 中检测到双重空闲,组合
- sql - SQL 子查询未分组
- google-apps-script - IMPORTRANGE 应用程序脚本
- java - TMC bean:缺少 JDK,需要运行某些 NetBeans 模块
- node.js - RequestRoute 和 RequestToken 的节点 s3.WriteGetObjectResponse 基本配置