[SPRING] @Cacheable에 TTL을 설정할 수 있습니까?
SPRING@Cacheable에 TTL을 설정할 수 있습니까?
나는 Spring 3.1에 대한 @Cacheable 주석 지원을 시도하고 있으며 TTL을 설정하여 캐시 된 데이터를 지우는 방법이 있는지 궁금하십니까? 지금 당장 볼 수 있듯이 @CacheEvict를 사용하여 나 자신을 지울 필요가 있습니다. @Scheduled와 함께 사용하면 TTL 구현을 직접 만들 수 있지만 그렇게 간단한 작업을하는 것처럼 보입니다.
해결법
-
==============================
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.스프링 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.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.나는 이런 삶의 해킹을 사용한다.
나는 이런 삶의 해킹을 사용한다.
@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.봄 부팅 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.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.Spring-boot 1.3.3부터 CacheManagerCustomizer 콜백 빈에서 RedisCacheManager.setExpires 또는 RedisCacheManager.setDefaultExpiration을 사용하여 CacheManager에서 만료 시간을 설정할 수 있습니다.
Spring-boot 1.3.3부터 CacheManagerCustomizer 콜백 빈에서 RedisCacheManager.setExpires 또는 RedisCacheManager.setDefaultExpiration을 사용하여 CacheManager에서 만료 시간을 설정할 수 있습니다.
-
==============================
8.Redis와 Java 8을 사용한다면 JetCache를 살펴볼 수 있습니다 :
Redis와 Java 8을 사용한다면 JetCache를 살펴볼 수 있습니다 :
@Cached (만료 = 10, timeUnit = TimeUnit.MINUTES) 사용자 getUserById (긴 userId);
from https://stackoverflow.com/questions/8181768/can-i-set-a-ttl-for-cacheable by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring 관리 컨텍스트 외부의 클래스에 bean 삽입 (0) | 2018.12.11 |
---|---|
[SPRING] Jackson JSON을 사용하여 Spring MVC에서 JSON 구문 분석하기 (0) | 2018.12.11 |
[SPRING] Spring Quartz 작업 실행이 겹치지 않도록한다. (0) | 2018.12.11 |
[SPRING] @Transactional 읽기 전용 전파 스프링 (0) | 2018.12.11 |
[SPRING] @RequestBody와 @RequestParam의 차이점은 무엇입니까? (0) | 2018.12.11 |