为什么@Cacheable在第二次调用方法后不起作用

时间:2018-09-20 20:36:45

标签: spring spring-cache

弄清楚可缓存对我不起作用,因为带有@Cacheable批注的方法在具有这种结构的类内。 我有

public interface Filter<T> {
    List<T> filter(int limit);
} 

和一系列实现:

@Component
public class UpcomingFilter implements Filter<Entity> {

    @Cacheable(value = {"upcoming"})
    @Override
    public List<Entity> filter(int limit) {
       //retrieve from repository
    }
}

@Component
public class RecentlyAddedFilter implements Filter<Entity> {
@Cacheable(value = {"recentlyAdded"})
    @Override
    public List<Entity> filter(int limit) {
       //retrieve from repository
    }
}
//and 6 more implementations

为了优化此过滤器的自动装配,我使用了HashMap,并在其中保存了这些过滤器:

@EnableAspectJAutoProxy
@ComponentScan
@Configuration
public class AppConfig {

    @Bean("filtersMap")
    public Map<String, Filter> filters() {
        Map<String, Filter> filtersMap = new HashMap<>();

        filtersMap.put("upcomingFilter", new UpcomingFilter(sessionRepository));
        filtersMap.put("recentlyAddedFilter", new RecentlyAddedFilter(entityRepository));
        //..another filters
        return filtersMap;
    }

    }

然后我将此地图自动连接到服务层:

@Qualifier("filtersMap") Map<String, Filter> filterMap

缓存配置:

@EnableCaching
@Configuration
public class CacheConfiguration {
    @Bean
    public CacheManager cacheManager() {
        String[] cacheNames = new String[] {"upcoming", "recentlyAdded"};
        return new ConcurrentMapCacheManager(cacheNames);
    }

}

然后在每种过滤器方法中执行sysout并衡量执行时间。 它显示了每次都会调用可缓存方法,并且不使用缓存。 比起我创建简单的类 MyFilter 而不实现 Filter 接口, 使用 @Cacheable 注释其方法,它的工作原理就像一个超级按钮。 因此,如何解决缓存不适用于实现 Filter 接口

的类的问题

1 个答案:

答案 0 :(得分:0)

通过此链接Method annotated with @Cacheable not getting intercepted找到了解决方案 并由尼古拉斯(Nikolas)评论:

在Cache Configuration类中添加具有@Cacheable批注的Service bean:

@EnableCaching
@Configuration
public class CacheConfiguration {

    @Bean
    public CacheManager cacheManager() {
        String[] cacheNames = new String[] {"upcoming", "recentlyAdded"};
        return new ConcurrentMapCacheManager(cacheNames);
    }

    @Bean
    public PopularFilter popularFilter() {
        return new PopularFilter(myRepository);
    }

     @Bean("filtersMap")
public Map<String, Filter> filters() {
    Map<String, Filter> filtersMap = new HashMap<>();
    filtersMap.put("popularFilter", popularFilter());
    //...
    return filtersMap;
}