首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring创建自定义CacheManager

Spring创建自定义CacheManager
EN

Stack Overflow用户
提问于 2016-06-13 07:52:35
回答 2查看 23.2K关注 0票数 6

我正在使用Spring和EhCache开发一个日历应用程序。我试图缓存以下方法:

代码语言:javascript
复制
@Override
@Cacheable(value = "concerts")
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception {
    return fetchEventsFromTheServer(eventsForUser, startDate, endDate);
}

挑战是我想要操作返回的缓存结果。例如,检查给定日期是否存在缓存,但是否存在不同的用户,然后返回(只要两个用户都满足特定条件)。

因此,在返回结果之前,我想:

  • 获取所有缓存项的列表。
  • 循环遍历它们并检查所需的日期/用户
  • 如果找到合适的话-返回
  • 如果找不到-缓存不可用,请运行该方法。

我认为最好的方法是创建一个自定义缓存管理器,它将对缓存音乐会执行所有操作,并对所有其他方法使用默认的自动配置缓存,但我无法让我的自定义管理器工作,也没有找到任何关于如何实现自定义CacheManager的好示例。

以下是我所拥有的:

Application.java:

代码语言:javascript
复制
@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

代码语言:javascript
复制
@Component
public class EventsCacheManager implements CacheManager  {

    @Override
    public Cache getCache(String s) {
        return null;
    }

    @Override
    public Collection<String> getCacheNames() {
        return null;
    }
}

EventsCacheManager.java -如何实现它?

代码语言:javascript
复制
@Component
public class EventsCacheManager implements CacheManager  {

    @Override
    public Cache getCache(String s) {
        return null;
    }

    @Override
    public Collection<String> getCacheNames() {
        return null;
    }
}

如果有人能给我一个如何实现我的自定义CacheManager的例子,我将非常感激。

EN

回答 2

Stack Overflow用户

发布于 2016-06-13 19:04:37

我没有花太多时间考虑您的需求/用例,但我确实认为,假设“自定义”CacheManager逻辑是正确的,自定义CacheManager会在这种情况下工作。

因此,默认情况下,Spring在上下文中查找名称为"cacheManager“的bean,并将其用于所有缓存操作。在您的配置中,您显然定义了2个"CacheManagers“.

代码语言:javascript
复制
@Bean(name = "eventsCacheManager")
public EventsCacheManager eventsCacheManager() {

    return new EventsCacheManager();
}

@Primary
@Bean(name = "cacheManager")
public CacheManager cacheManager() {
    return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}

即"eventsCacheManager“(自定义)和"cacheManager”(标准)。实际上,您甚至将"cacheManager“标记为主(使用@Primary注释)。当然,如果您不这样做,Spring肯定会抱怨,因为在执行自动连接(默认为按类型自动连接)时,在上下文中找到了超过一个给定类型的bean (即CacheManager)。

因此,为了调用特定服务调用在运行时使用的缓存管理策略(即CacheManager),还需要告诉Spring使用哪种CacheManager (又名策略),比如.

代码语言:javascript
复制
@Override
@Cacheable(value = "concerts", cacheManager="eventsCacheManager")
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception {
    return fetchEventsFromTheServer(eventsForUser, startDate, endDate);
}

例如,在cacheManager注释中使用@Cacheable属性来指示使用哪种缓存策略。

有关更多细节,请参见Spring在自定义缓存解析上的参考文档。

希望这能让你走。

票数 2
EN

Stack Overflow用户

发布于 2016-06-14 07:26:23

根据我对你问题的理解,我相信你看问题的方式是错误的。

不必浏览缓存内容来提取派生信息,您应该在加载主数据时将派生信息插入缓存。

例如,当加载基于月份的信息时,请立即将其分解为基于日的信息,并将其放入缓存中。

这种描述还应该清楚地表明,您想要做的事情超出了Spring缓存抽象的能力,因为您需要自定义缓存加载逻辑。

因此,我不建议对CacheManager进行黑客攻击以隐藏该逻辑,而是对数据加载逻辑进行攻击。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37784371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档