@Cacheable için bir TTL ayarlayabilir miyim


109

@CacheableBahar 3.1 için açıklama desteğini deniyorum ve bir süre sonra bir TTL ayarlayarak önbelleğe alınan verileri temizlemenin bir yolu olup olmadığını merak ediyorum. Şu anda görebildiğim kadarıyla @CacheEvict, ve bunu kullanarak kendim @Scheduledbir TTL uygulaması yapabilirim ama bu kadar basit bir görev için biraz fazla görünüyor?

Yanıtlar:


39

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

TTL / TTI / Tahliye politikasını / XXX özelliğini nasıl ayarlayabilirim?

Doğrudan önbellek sağlayıcınız aracılığıyla. Önbellek soyutlaması ... şey, bir önbellek uygulaması değil bir soyutlamadır

Bu nedenle, EHCache kullanıyorsanız, TTL'yi yapılandırmak için EHCache'nin yapılandırmasını kullanın.

Guava'nın CacheBuilder'ı bir önbellek oluşturmak için de kullanabilir ve bu önbelleğin ConcurrentMap görünümünü ConcurrentMapCacheFactoryBean'in setStore yöntemine geçirebilirsiniz .


58

Bahar 3.1 ve 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();
    }

}

21
Spring 4.1 için CachingConfigurerSupport'u genişletin ve yalnızca cacheManager () üzerine yazın.
Johannes Flügel

40

Baharda Guava Önbelleği kurmanın tam bir örneği. Guava'yı Ehcache yerine kullandım çünkü bu biraz daha hafif ve yapılandırma bana daha açık geldi.

Maven Bağımlılıklarını İçe Aktar

Bu bağımlılıkları maven pom dosyanıza ekleyin ve temiz ve paketleri çalıştırın. Bu dosyalar, CacheBuilder'da kullanılmak üzere Guava dep ve Spring yardımcı yöntemleridir.

    <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>

Önbelleği Yapılandırın

Java yapılandırmasını kullanarak önbelleği yapılandırmak için bir CacheConfig dosyası oluşturmanız gerekir.

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

Önbelleğe alınacak yönteme açıklama ekleyin

@Cacheable açıklamasını ekleyin ve önbellek adını girin.

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

Ek açıklamalı ekran görüntüleriyle burada daha eksiksiz bir örnek görebilirsiniz: İlkbaharda Guava Önbelleği


2
Not: Guava önbelleği artık İlkbahar 5'te kullanımdan kaldırıldı ( stackoverflow.com/questions/44175085/… )
Amin

36

Hayat hacklemeyi böyle kullanıyorum

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

reportCacheEvictHerhangi bir yerden yöntemi mi arıyorsunuz ? CacheEvict nasıl oluyor?
Jaikrat

Anla. Bu yöntemi hiçbir yerden aramıyoruz. FixedDelay zaman aralığından sonra çağrılır. İpucu için teşekkürler.
Jaikrat

1
Önbelleğin tamamını bir programa göre temizlemek, işleri yürütmek için kullanışlı bir hack olabilir, ancak bu yöntem öğelere bir TTL vermek için kullanılamaz. Hatta durum değeri sadece tüm önbelleği silmek isteyip ilan edebilir. Bunun altında yatan gerçek, ConcurrentMapCache'nin nesneleri herhangi bir zaman damgası olmadan depolamasıdır, bu nedenle bir TTL'yi olduğu gibi değerlendirmenin bir yolu yoktur.
jmb

pantolon koltuğu kodudur (bu yöntem karalandı :)).
Atum

Güzel ve temiz bir yaklaşım
lauksas

31

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;
}

}

ve

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

İnanılmaz! Tam olarak aradığım
buydu

7

bu, org.springframework.cache.interceptor.CacheInterceptor'ı genişleterek ve "doPut" yöntemini geçersiz kılarak yapılabilir - org.springframework.cache.interceptor.AbstractCacheInvoker geçersiz kılma mantığınız önbellek girişi için TTL ayarlamayı bilen önbellek sağlayıcı koyma yöntemini kullanmalıdır (benim durumumda HazelcastCacheManager kullanıyorum)

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



}

önbellek yapılandırmanızda, özel durdurucu örneğinizi oluşturarak bu 2 fasulye yöntemini eklemeniz gerekir.

@Bean
public CacheOperationSource cacheOperationSource() {
    return new AnnotationCacheOperationSource();
}


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

Bu çözüm, TTL'yi genel olarak önbellek düzeyinde değil, giriş düzeyinde ayarlamak istediğinizde iyidir.


2

İlkbahar önyüklemesi 1.3.3'ten bu yana , CacheManagerCustomizer geri arama fasulyesinde RedisCacheManager.setExpires veya RedisCacheManager.setDefaultExpiration'ı kullanarak CacheManager'da sona erme süresini ayarlayabilirsiniz .


1

Redis kullanılırken, TTL aşağıdaki gibi özellikler dosyasında ayarlanabilir:

spring.cache.redis.time-to-live=1d # 1 day

spring.cache.redis.time-to-live=5m # 5 minutes

spring.cache.redis.time-to-live=10s # 10 seconds


-2

Redis ve Java 8 ile çalışıyorsanız, JetCache'ye bir göz atabilirsiniz :

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


1
soru bahar içindir @Cacheable annotation
satyesht
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.