首页 文章

我可以为@Cacheable设置TTL吗?

提问于
浏览
68

我正在尝试对Spring 3.1的 @Cacheable 注释支持,并想知道是否有任何方法可以通过设置TTL在一段时间后清除缓存的数据?现在从我所看到的我需要通过使用 @CacheEvict 来清除它,并且与 @Scheduled 一起使用我可以自己做一个TTL实现但是对于这么简单的任务似乎有点多了?

8 回答

  • 2

    Spring 3.1和Guava 1.13.1:

    @EnableCaching
    @Configuration
    public class CacheConfiguration implements CachingConfigurer {
    
        @Override
        public CacheManager cacheManager() {
            ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager() {
    
                @Override
                protected Cache createConcurrentMapCache(final String name) {
                    return new ConcurrentMapCache(name,
                        CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).maximumSize(100).build().asMap(), false);
                }
            };
    
            return cacheManager;
        }
    
        @Override
        public KeyGenerator keyGenerator() {
            return new DefaultKeyGenerator();
        }
    
    }
    
  • 3

    我使用像这样的生活黑客

    @Configuration
    @EnableCaching
    @EnableScheduling
    public class CachingConfig {
        public static final String GAMES = "GAMES";
        @Bean
        public CacheManager cacheManager() {
            ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(GAMES);
    
            return cacheManager;
        }
    
    @CacheEvict(allEntries = true, value = {GAMES})
    @Scheduled(fixedDelay = 10 * 60 * 1000 ,  initialDelay = 500)
    public void reportCacheEvict() {
        System.out.println("Flush Cache " + dateFormat.format(new Date()));
    }
    
  • 23

    http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#cache-specific-config

    如何设置TTL / TTI /逐出政策/ XXX功能?直接通过缓存提供程序 . 缓存抽象是......好吧,抽象不是缓存实现

    因此,如果您使用EHCache,请使用EHCache的配置来配置TTL .

    您还可以使用Guava的CacheBuilder来构建缓存,并将此缓存的ConcurrentMap视图传递给setStore method of the ConcurrentMapCacheFactoryBean .

  • 32

    如果您正在使用redis和Java 8,可以查看JetCache

    @Cached(expire = 10, timeUnit = TimeUnit.MINUTES) User getUserById(long userId);

  • 40

    这可以通过扩展org.springframework.cache.interceptor.CacheInterceptor来完成,并覆盖“doPut”方法 - org.springframework.cache.interceptor.AbstractCacheInvoker你的覆盖逻辑应该使用知道为缓存条目设置TTL的缓存提供者put方法(在我的例子中,我使用HazelcastCacheManager)

    @Autowired
    @Qualifier(value = "cacheManager")
    private CacheManager hazelcastCacheManager;
    
    @Override
    protected void doPut(Cache cache, Object key, Object result) {
            //super.doPut(cache, key, result); 
            HazelcastCacheManager hazelcastCacheManager = (HazelcastCacheManager) this.hazelcastCacheManager;
            HazelcastInstance hazelcastInstance = hazelcastCacheManager.getHazelcastInstance();
            IMap<Object, Object> map = hazelcastInstance.getMap("CacheName");
            //set time to leave 18000 secondes
            map.put(key, result, 18000, TimeUnit.SECONDS);
    
    
    
    }
    

    在缓存配置上,您需要添加这两个bean方法,创建自定义拦截器实例 .

    @Bean
    public CacheOperationSource cacheOperationSource() {
        return new AnnotationCacheOperationSource();
    }
    
    
    @Primary
    @Bean
    public CacheInterceptor cacheInterceptor() {
        CacheInterceptor interceptor = new MyCustomCacheInterceptor();
        interceptor.setCacheOperationSources(cacheOperationSource());    
        return interceptor;
    }
    

    当您想要在入门级别设置TTL而不是在缓存级别上全局设置时,此解决方案很好

  • 20

    从Spring-boot 1.3.3开始,您可以使用CacheManagerCustomizer回调bean中的RedisCacheManager.setExpires或RedisCacheManager.setDefaultExpiration在CacheManager中设置过期时间 .

  • 29

    以下是在Spring中设置Guava Cache的完整示例 . 我使用Guava而不是Ehcache,因为它的重量有点轻,配置似乎对我来说更直接 .

    Import Maven Dependencies

    将这些依赖项添加到您的maven pom文件并运行clean和packages . 这些文件是用于CacheBuilder的Guava dep和Spring辅助方法 .

    <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
    

    Configure the Cache

    您需要创建CacheConfig文件以使用Java配置来配置缓存 .

    @Configuration
    @EnableCaching
    public class CacheConfig {
    
       public final static String CACHE_ONE = "cacheOne";
       public final static String CACHE_TWO = "cacheTwo";
    
       @Bean
       public Cache cacheOne() {
          return new GuavaCache(CACHE_ONE, CacheBuilder.newBuilder()
                .expireAfterWrite(60, TimeUnit.MINUTES)
                .build());
       }
    
       @Bean
       public Cache cacheTwo() {
          return new GuavaCache(CACHE_TWO, CacheBuilder.newBuilder()
                .expireAfterWrite(60, TimeUnit.SECONDS)
                .build());
       }
    }
    

    Annotate the method to be cached

    添加@Cacheable注释并传入缓存名称 .

    @Service
    public class CachedService extends WebServiceGatewaySupport implements CachedService {
    
        @Inject
        private RestTemplate restTemplate;
    
    
        @Cacheable(CacheConfig.CACHE_ONE)
        public String getCached() {
    
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
    
            HttpEntity<String> reqEntity = new HttpEntity<>("url", headers);
    
            ResponseEntity<String> response;
    
            String url = "url";
            response = restTemplate.exchange(
                    url,
                    HttpMethod.GET, reqEntity, String.class);
    
            return response.getBody();
        }
    }
    

    您可以在此处看到更完整的示例,并带有带注释的屏幕截图:Guava Cache in Spring

  • 1

    Springboot 1.3.8

    import java.util.concurrent.TimeUnit;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.guava.GuavaCacheManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import com.google.common.cache.CacheBuilder;
    
    @Configuration
    @EnableCaching
    public class CacheConfig extends CachingConfigurerSupport {
    
    @Override
    @Bean
    public CacheManager cacheManager() {
        GuavaCacheManager cacheManager = new GuavaCacheManager();
        return cacheManager;
    }
    
    @Bean
    public CacheManager timeoutCacheManager() {
        GuavaCacheManager cacheManager = new GuavaCacheManager();
        CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(5, TimeUnit.SECONDS);
        cacheManager.setCacheBuilder(cacheBuilder);
        return cacheManager;
    }
    
    }
    

    @Cacheable(value="A", cacheManager="timeoutCacheManager")
    public Object getA(){
    ...
    }
    

相关问题