我试图让Ehcache 3在不使用Spring引导的情况下使用Spring 4.
这是一个使用Spring Boot的工作示例,但我正在处理一个不使用Spring Boot的现有应用程序.
问题是spring-context-support(添加Spring的缓存注释)要求Ehcache的CacheManager在这个类路径上:net.sf.ehcache.CacheManager
但是,在Ehcache 3中,CacheManager类驻留在另一个类路径上:org.ehcache.CacheManager.
所以,基本上spring-context-support不支持Ehcache 3.你必须直接使用JSR-107注释,而不是Spring提供的注释.
但显然它适用于Spring Boot.也许有一种方法可以使它与标准的Spring应用程序一起工作.这就是我所希望的.我真的想要使用Spring自己的注释而不是JSR-107注释.
我有一个服务,它调用外部系统通过外部 ID 检索某种对象并将它们提交回更新。有一种更通用的方法,而不是一个接一个地检索对象:
public interface ExternalSystem {
List<ExternalDTO> getObjects(List<String> externalIds);
void updateObjects(List<ExternalDTO> updates);
}
Run Code Online (Sandbox Code Playgroud)
我想在外部系统调用之上放置一个缓存,因为它们非常昂贵。
在服务的实现中我可以简单地添加spring注释:
@Cacheable("cache-external")
List<ExternalDTO> getObjects(List<String> externalIds) {}
@CacheEvict(cacheNames="cache-external", allEntries=true)
void updateObjects(List<ExternalDTO> updates);
Run Code Online (Sandbox Code Playgroud)
但是,如果 externalId 之间有很多交集,这样的缓存会表现得非常糟糕,即
所以,问题是如何实现自定义策略(我认为它不能开箱即用),该策略将仅逐出那些真正应该逐出的条目,并使键以从缓存中检索相交对象的方式?
更新。我发现了两个类似的问题:
更新2。 这与我想要的类似,只是我将为集合中的每个项目放入 String 和ExternalDTO 的缓存对。 列表到列表的元素级缓存
我故意在我的类路径中添加了几个不同的缓存提供程序。我有用于分布式缓存的 Hazelcast 和用于本地缓存的 Caffeine。我正在尝试使用 JCache (JSR107) 注释来缓存我的值。
我已经创建了一个 CacheResolverFactory ,它将能够检测要从哪个提供程序使用哪个缓存管理器(基于方法注释),但是当我启动应用程序时,我收到以下错误消息:
Exception in thread "Thread-2" javax.cache.CacheException: Multiple CachingProviders have been configured when only a single CachingProvider is expected
at javax.cache.Caching$CachingProviderRegistry.getCachingProvider(Caching.java:386)
at javax.cache.Caching$CachingProviderRegistry.getCachingProvider(Caching.java:361)
at javax.cache.Caching.getCachingProvider(Caching.java:151)
at org.jsr107.ri.annotations.DefaultCacheResolverFactory.<init>(DefaultCacheResolverFactory.java:59)
at org.jsr107.ri.annotations.cdi.CacheLookupUtil.<init>(CacheLookupUtil.java:45)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
Run Code Online (Sandbox Code Playgroud)
显然,我知道我有多个缓存提供程序。但是,我似乎无法找到有关此问题的任何信息。该类org.jsr107.ri.annotations.cdi.CacheLookupUtil有一个私有 CacheResolverFactory 成员,该成员在构造时初始化为需要单个 CacheProvider 的 DefaultCacheResolverFactory()。
public class CacheLookupUtil extends AbstractCacheLookupUtil<InvocationContext> {
@Inject
private BeanManagerUtil beanManagerUtil;
private CacheKeyGenerator defaultCacheKeyGenerator = new DefaultCacheKeyGenerator();
private CacheResolverFactory defaultCacheResolverFactory = new DefaultCacheResolverFactory();
...
...
}
Run Code Online (Sandbox Code Playgroud)
我可以做些什么来避免这个问题吗?JCache …
我正在尝试将缓存添加到springboot应用程序,并且我遇到了在启动期间抛出org.ehcache.jsr107.MultiCacheException异常的问题.
我使用以下(全部通过Maven pom文件加载):Springboot 1.5.5,Ehcache 3.3.1,Javax缓存1.0.0
我的SpringBootApplication看起来像这样:
@SpringBootApplication
@EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个包含以下内容的CacheConfig类:
@Component
public class CacheConfig implements JCacheManagerCustomizer{
@Override
public void customize(javax.cache.CacheManager cacheManager) {
cacheManager.createCache("item", new MutableConfiguration<>()
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 5)))
.setStoreByValue(false)
.setStatisticsEnabled(true));
}
}
Run Code Online (Sandbox Code Playgroud)
我的ehcache.xml文件包含:
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'>
<service>
<jsr107:defaults>
<jsr107:cache name="item" template="heap-cache"/>
</jsr107:defaults>
</service>
<cache-template name="heap-cache">
<listeners>
<listener>
<class>org.terracotta.ehcache.EventLogger</class>
<event-firing-mode>ASYNCHRONOUS</event-firing-mode>
<event-ordering-mode>UNORDERED</event-ordering-mode>
<events-to-fire-on>CREATED</events-to-fire-on>
<events-to-fire-on>UPDATED</events-to-fire-on>
<events-to-fire-on>EXPIRED</events-to-fire-on>
<events-to-fire-on>REMOVED</events-to-fire-on>
<events-to-fire-on>EVICTED</events-to-fire-on>
</listener>
</listeners>
<resources>
<heap unit="entries">2000</heap>
<offheap unit="MB">100</offheap>
</resources>
</cache-template>
</config>
Run Code Online (Sandbox Code Playgroud)
测试项服务包含: …
我必须使用EhCache实现缓存。基本要求是,我必须将该缓存的对象保持固定的时间间隔(现在在下面的代码中保持1小时)。因此,我实现了如下代码:
样本域对象:
import lombok.*;
@Getter
@Setter
@ToString
@AllArgsConstructor
public class City implements Serializable {
public String name;
public String country;
public int population;
}
Run Code Online (Sandbox Code Playgroud)
缓存管理器类:
import net.sf.ehcache.*;
public class JsonObjCacheManager {
private static final Logger logger = LoggerFactory.getLogger(JsonObjCacheManager.class);
private CacheManager manager;
private Cache objectCache;
public JsonObjCacheManager(){
manager = CacheManager.create();
objectCache = manager.getCache("jsonDocCache");
if( objectCache == null){
objectCache = new Cache(
new CacheConfiguration("jsonDocCache", 1000)
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
.eternal(false)
.timeToLiveSeconds(60 * 60)
.timeToIdleSeconds(0)
.diskExpiryThreadIntervalSeconds(0)
.persistence(new PersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.LOCALTEMPSWAP)));
objectCache.disableDynamicFeatures();
manager.addCache(objectCache);
}
}
public List<String> …Run Code Online (Sandbox Code Playgroud) 我正在编写一个使用 Hazelcast(JCache 标准)进行缓存的分布式应用程序。
我有一个用例,我应该对集群中的特定键加锁,以防止更新期间调用。
我知道 EhCache 有一个非常相似的东西,它叫做 acquireReadLockOnKey(Object key)。
如何使用 JCache 和/或 Hazelcast 实现这种锁定?