Spring Cache-创建自定义CacheManager

Ole*_*leg 6 java ehcache spring-boot spring-cache

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

@Override
@Cacheable(value = "concerts")
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception {
    return fetchEventsFromTheServer(eventsForUser, startDate, endDate);
}
Run Code Online (Sandbox Code Playgroud)

挑战是我想操纵返回的缓存结果。例如,检查是否存在给定日期但另一个用户的缓存,然后取而代之(只要两个用户都符合特定条件)。

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

  • 获取所有缓存条目的列表
  • 遍历所有这些,并检查所需的日期/用户
  • 如果找到合适的-退还
  • 如果未找到-缓存不可用,请运行该方法。

我认为最好的办法是创建一个自定义缓存管理器,该缓存管理器将对缓存的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;
    }


}
Run Code Online (Sandbox Code Playgroud)

EventsCacheManager.java

@Component
public class EventsCacheManager implements CacheManager  {

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

    @Override
    public Collection<String> getCacheNames() {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

EventsCacheManager.java-如何实现?

@Component
public class EventsCacheManager implements CacheManager  {

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

    @Override
    public Collection<String> getCacheNames() {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果有人能给我一个有关如何实现自定义的示例,我将不胜感激 CacheManager

Joh*_*lum 2

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

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

@Bean(name = "eventsCacheManager")
public EventsCacheManager eventsCacheManager() {

    return new EventsCacheManager();
}

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

即“eventsCacheManager”(自定义)和“cacheManager”(标准)。事实上,您甚至将“cacheManager”标记为主要(使用注释@Primary)。当然,如果你不这样做,SpringCacheManager肯定会抱怨,因为在执行自动装配(默认为按类型自动装配)时,在上下文中发现了超过 1 个给定类型(即 )的 bean 。

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

@Override
@Cacheable(value = "concerts", cacheManager="eventsCacheManager")
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception {
    return fetchEventsFromTheServer(eventsForUser, startDate, endDate);
}
Run Code Online (Sandbox Code Playgroud)

即使用注解cacheManager中的属性@Cacheable来指示使用哪种缓存策略。

有关更多详细信息,请参阅 Spring 的关于自定义缓存解析的参考文档。

希望这有助于您继续前进。