我正在使用Spring Boot和EhCache开发日历应用程序。 我正在尝试缓存以下方法:
@Override
@Cacheable(value = "concerts")
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception {
return fetchEventsFromTheServer(eventsForUser, startDate, endDate);
}
挑战是我想操纵返回的缓存结果。例如,检查是否存在给定日期的缓存,但是对于不同的用户,然后返回它(只要两个用户都满足特定条件)。
所以,在返回结果之前我想:
我认为最好的方法是创建一个自定义缓存管理器,它将使用缓存的Concert进行所有操作,并为所有其他方法使用默认的自动配置缓存,但我无法让我的自定义管理器工作而不是找到关于如何实现自定义CacheManager的任何好例子。
这就是我所拥有的:
Application.java:
@SpringBootApplication
@ComponentScan
@EnableCaching
@EnableScheduling
public class SpringBootWebApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<SpringBootWebApplication> applicationClass = SpringBootWebApplication.class;
@Bean(name = "eventsCacheManager")
public EventsCacheManager eventsCacheManager() {
return new EventsCacheManager();
}
@Primary
@Bean(name = "cacheManager")
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
cmfb.setShared(true);
return cmfb;
}
}
EventsCacheManager.java
@Component
public class EventsCacheManager implements CacheManager {
@Override
public Cache getCache(String s) {
return null;
}
@Override
public Collection<String> getCacheNames() {
return null;
}
}
EventsCacheManager.java - 如何实现它?
@Component
public class EventsCacheManager implements CacheManager {
@Override
public Cache getCache(String s) {
return null;
}
@Override
public Collection<String> getCacheNames() {
return null;
}
}
如果有人可以举例说明我应该如何实施自定义CacheManager
答案 0 :(得分:2)
我没有花太多时间考虑您的需求/用例,但我认为自定义CacheManager
可以在这种情况下工作,假设&#34; custom&#34; CacheManager
逻辑是正确的。
因此,默认情况下, Spring 在上下文中查找名为&#34; cacheManager&#34;的bean。并将其用于所有缓存操作。在您的配置中,您显然拥有2&#34; CacheManagers&#34;定义...
@Bean(name = "eventsCacheManager")
public EventsCacheManager eventsCacheManager() {
return new EventsCacheManager();
}
@Primary
@Bean(name = "cacheManager")
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
即。 &#34; eventsCacheManager&#34; (自定义)和&#34; cacheManager&#34; (标准)。实际上,您甚至标记了&#34; cacheManager&#34;作为主要(使用@Primary
注释)。当然,如果你没有这样做, Spring 肯定会抱怨,因为在执行自动布线时,在上下文中找到了超过1个给定类型的bean(即CacheManager
)(默认为按类型自动连接。)
因此,为了调出在运行时使用特定服务调用的缓存管理策略(即CacheManager
),您还需要告诉 Spring {{1} }(又名策略)使用,像这样......
CacheManager
即。使用@Override
@Cacheable(value = "concerts", cacheManager="eventsCacheManager")
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception {
return fetchEventsFromTheServer(eventsForUser, startDate, endDate);
}
注释中的cacheManager
属性来指示要使用的缓存策略。
有关详细信息,请参阅Custom cache resolution上的Spring的参考文档。
希望这有助于您前进。
答案 1 :(得分:1)
从我对你的问题的理解,我相信你是以错误的方式看问题。
您不必浏览缓存内容以提取派生信息,而应在加载主数据时将衍生信息插入缓存中。
例如,在加载基于月份的信息时,立即将其分解为基于日期的信息,并将其放入缓存中。
此描述还应清楚地表明您想要做的事情超出了Spring缓存抽象的功能,因为您需要自定义缓存加载逻辑。
因此我不建议攻击CacheManager
来隐藏该逻辑,而是从数据加载逻辑中执行此操作。