복붙노트

[SPRING] @Cacheable에 TTL을 설정할 수 있습니까?

SPRING

@Cacheable에 TTL을 설정할 수 있습니까?

나는 Spring 3.1에 대한 @Cacheable 주석 지원을 시도하고 있으며 TTL을 설정하여 캐시 된 데이터를 지우는 방법이 있는지 궁금하십니까? 지금 당장 볼 수 있듯이 @CacheEvict를 사용하여 나 자신을 지울 필요가 있습니다. @Scheduled와 함께 사용하면 TTL 구현을 직접 만들 수 있지만 그렇게 간단한 작업을하는 것처럼 보입니다.

해결법

  1. ==============================

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

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

    따라서 EHCache를 사용하는 경우 EHCache 구성을 사용하여 TTL을 구성하십시오.

    또한 Guava의 CacheBuilder를 사용하여 캐시를 작성하고이 캐시의 ConcurrentMap보기를 ConcurrentMapCacheFactoryBean의 setStore 메소드에 전달할 수 있습니다.

  2. ==============================

    2.스프링 3.1 및 구아바 1.13.1 :

    스프링 3.1 및 구아바 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. ==============================

    3.Spring에서 Guava Cache를 설정하는 예제입니다. 그것이 더 가벼운 무게이기 때문에 나는 구아바를 Ehcache보다 더 많이 사용했다. 그리고 설정은 나에게 곧은 것 같았다.

    Spring에서 Guava Cache를 설정하는 예제입니다. 그것이 더 가벼운 무게이기 때문에 나는 구아바를 Ehcache보다 더 많이 사용했다. 그리고 설정은 나에게 곧은 것 같았다.

    Maven 의존성 가져 오기

    이 의존성을 당신의 maven pom 파일에 추가하고 clean과 패키지를 실행하십시오. 이 파일들은 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>
    

    캐시 구성

    Java 구성을 사용하여 캐시를 구성하려면 CacheConfig 파일을 작성해야합니다.

    @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());
       }
    }
    

    캐싱 할 메소드에 주석 달기

    @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

  4. ==============================

    4.나는 이런 삶의 해킹을 사용한다.

    나는 이런 삶의 해킹을 사용한다.

    @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()));
    }
    
  5. ==============================

    5.봄 부팅 1.3.8

    봄 부팅 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(){
    ...
    }
    
  6. ==============================

    6.org.springframework.cache.interceptor.CacheInterceptor를 확장하고 "doPut"메소드를 오버라이드하면된다. org.springframework.cache.interceptor.AbstractCacheInvoker 당신의 재정의 로직은 캐시 엔트리를위한 TTL을 설정하는 것을 알고있는 캐시 제공자 put 메소드를 사용해야한다 (나의 경우 HazelcastCacheManager를 사용한다)

    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을 설정하고 캐시 레벨에서 전역으로 설정하지 않으려 고 할 때 유용합니다.

  7. ==============================

    7.Spring-boot 1.3.3부터 CacheManagerCustomizer 콜백 빈에서 RedisCacheManager.setExpires 또는 RedisCacheManager.setDefaultExpiration을 사용하여 CacheManager에서 만료 시간을 설정할 수 있습니다.

    Spring-boot 1.3.3부터 CacheManagerCustomizer 콜백 빈에서 RedisCacheManager.setExpires 또는 RedisCacheManager.setDefaultExpiration을 사용하여 CacheManager에서 만료 시간을 설정할 수 있습니다.

  8. ==============================

    8.Redis와 Java 8을 사용한다면 JetCache를 살펴볼 수 있습니다 :

    Redis와 Java 8을 사용한다면 JetCache를 살펴볼 수 있습니다 :

    @Cached (만료 = 10, timeUnit = TimeUnit.MINUTES) 사용자 getUserById (긴 userId);

  9. from https://stackoverflow.com/questions/8181768/can-i-set-a-ttl-for-cacheable by cc-by-sa and MIT license