3

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

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

@Data  
public static class LocalCacheSpec {  
    private Integer timeout;  
 private Integer max \= 500;  
}  
//该变量名称会与配置文件中相对应  
private Map<String, LocalCacheSpec> localCacheSpecs;

2.配置本地缓存CacheManager

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

3.配置application.yml

caching:  
 local-cache-specs: 
   test\_user\_map: 
     max: 15  
     timeout: 10  
   test\student\_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<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  
   test\student\_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();  
}


}

liumang
343 声望36 粉丝

一直在思考怎么结合自己擅长的知识做些什么。现在有了好主意坚持一年,看看会有什么改变,有什么美好的事情发生。