Springboot 2.x 同时使用Caffeine 和 Redis 及自定义缓存时间

一.实现本地缓存自定义配置

1.@Configuration配置类中,自定义bean实现本地缓存的灵活配置


`@Data
public static class LocalCacheSpec {

private Integer timeout;  

private Integer max = 500;
}
//该变量名称会与配置文件中相对应
private Map localCacheSpecs;`

2.配置本地缓存CacheManager


`@Bean
public CacheManager caffeineCacheManager(Ticker ticker) {

SimpleCacheManager manager = new SimpleCacheManager();  

if (localCacheSpecs != null) {

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

manager.setCaches(caches);
}

return manager;  

}`

3.配置application.yml


`caching:
local-cache-specs:
test_user_map:

 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值和配置文件中是对应起来的

二、实现Redis缓存过期时间自定义

1.添加RedisCacheManager


`
...
//映射配置文件中的配置,不同缓存,不同过期时间,变量名需要在配置文件中使用
private Map redisCacheSpecs;
...

@Bean
public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {

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

//不同缓存,不同过期时间
Map redisCacheConfigMap = new HashMap<>(redisCacheSpecs.size());
for (Map.Entry 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 localCacheSpecs;
private Map redisCacheSpecs;

@Bean
public CacheManager caffeineCacheManager(Ticker ticker) {

SimpleCacheManager manager = new SimpleCacheManager();  

if (localCacheSpecs != null) {

    List 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 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 redisCacheConfigMap = new HashMap<>(redisCacheSpecs.size());
for (Map.Entry 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();  

}

}`

你可能感兴趣的:(springboot,redis,缓存)