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

}

}`

相关文章
相关标签/搜索