Springboot 2.x 同時使用Caffeine 和 Redis 及自定義緩存時間

一.實現本地緩存自定義配置

1.@Configuration配置類中,自定義bean實現本地緩存的靈活配置redis


`@Data
public static class LocalCacheSpec {數據庫

private Integer timeout;

private Integer max = 500;
}
//該變量名稱會與配置文件中相對應
private Map<String, LocalCacheSpec> localCacheSpecs;`緩存

2.配置本地緩存CacheManagerapp


`@Bean
public CacheManager caffeineCacheManager(Ticker ticker) {ide

SimpleCacheManager manager = new SimpleCacheManager();

if (localCacheSpecs != null) {ui

List<CaffeineCache> caches = localCacheSpecs.entrySet().stream()  
                    .map(entry -> buildCache(entry.getKey(), entry.getValue(), ticker))  
                    .collect(Collectors.toList());

manager.setCaches(caches);
}code

return manager;

}`ci

3.配置application.ymlget


`caching:
local-cache-specs:
test_user_map:it

max: 15  
 timeout: 10

teststudent_map:

max: 100  
 timeout: 20`

4.在代碼中制定value


`@Override
@Cacheable(value = "test_user_map",,key = "'user:'+#id")
public User getUser(Integer id) {
//數據庫查詢用戶
User user = xxxx
reture user;
}`

其中 @Cacheable註解的value值和配置文件中是對應起來的

2、實現Redis緩存過時時間自定義

1.添加RedisCacheManager


`
...
//映射配置文件中的配置,不一樣緩存,不一樣過時時間,變量名須要在配置文件中使用
private Map<String,Integer> redisCacheSpecs;
...

@Bean
public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {

RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()  
        .entryTtl(Duration.ofHours(4))  
        .prefixKeysWith("test:")//緩存前綴  
        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

//不一樣緩存,不一樣過時時間
Map<String, RedisCacheConfiguration> redisCacheConfigMap = new HashMap<>(redisCacheSpecs.size());
for (Map.Entry<String, Integer> entry : redisCacheSpecs.entrySet()) {

redisCacheConfigMap.put(entry.getKey(), redisCacheConfiguration.entryTtl(Duration.ofSeconds(entry.getValue())));

}

return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))  
        .initialCacheNames(redisCacheSpecs.keySet())//這裏很重要  
        .withInitialCacheConfigurations(redisCacheConfigMap)  //這裏很重要
        .cacheDefaults(redisCacheConfiguration).build();

}`

2.如今已經有兩個CacheManager,這就須要@Primary制定一個默認的CacheManager


3.application.yml配置文件在caching下追加:


`redis-cache-specs:
schoole_detail: 30
city_detail: 30`

4.代碼中,制定value和cacheManager


`@Override
@Cacheable(value = "school_detail",cacheManager = "redisCacheManager",key = "'school:'+#id")
public School getSubVenueDetail(Long subVenueId) {
...
return school;
}`

以上就能實現本地和redis緩存配置,同時使用,也能夠分別配置過時時間。

application總體配置:
`caching:
local-cache-specs:
test_user_map:

max: 15  
 timeout: 10

teststudent_map:

max: 100  
 timeout: 20

redis-cache-specs:
schoole_detail: 30
city_detail: 30`

Cofig配置類:
`@ConfigurationProperties(prefix = "caching")
@Configuration
@Slf4j
@Data
public class CacheConfig {

@Data
public static class LocalCacheSpec {

private Integer timeout;  
private Integer max = 500;

}
//該變量名稱會與配置文件中相對應
private Map<String, LocalCacheSpec> localCacheSpecs;
private Map<String,Integer> redisCacheSpecs;

@Bean
public CacheManager caffeineCacheManager(Ticker ticker) {

SimpleCacheManager manager = new SimpleCacheManager();

if (localCacheSpecs != null) {

List<CaffeineCache> caches = localCacheSpecs.entrySet().stream()  
                    .map(entry -> buildCache(entry.getKey(), entry.getValue(), ticker))  
                    .collect(Collectors.toList());

manager.setCaches(caches);
}

return manager;

}

private CaffeineCache buildCache(String name, LocalCacheSpec cacheSpec, Ticker ticker) {

log.info("Cache {} specified timeout of {} min, max of {}", name, cacheSpec.getTimeout(), cacheSpec.getMax());

final Caffeine<Object, Object> caffeineBuilder

= Caffeine.newBuilder()  
        .expireAfterWrite(cacheSpec.getTimeout(), TimeUnit.SECONDS)  
        .maximumSize(cacheSpec.getMax())  
        .ticker(ticker);

return new CaffeineCache(name, caffeineBuilder.build());
}

@Bean
public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {

RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()  
        .entryTtl(Duration.ofHours(4))  
        .prefixKeysWith("test:")//緩存前綴  
        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

//不一樣緩存,不一樣過時時間
Map<String, RedisCacheConfiguration> redisCacheConfigMap = new HashMap<>(redisCacheSpecs.size());
for (Map.Entry<String, Integer> entry : redisCacheSpecs.entrySet()) {

redisCacheConfigMap.put(entry.getKey(), redisCacheConfiguration.entryTtl(Duration.ofSeconds(entry.getValue())));

}

return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))  
        .initialCacheNames(redisCacheSpecs.keySet())//這裏很重要  
        .withInitialCacheConfigurations(redisCacheConfigMap)  //這裏很重要
        .cacheDefaults(redisCacheConfiguration).build();

}

@Bean
public Ticker ticker() {

return Ticker.systemTicker();

}

}`

相關文章
相關標籤/搜索