cacheable是spring提供的快捷的缓存注解 使用起来非常方便
我们项目用的是redis缓存 配置如下:
@primary指定默认的cacheManager 默认是24小时 另外配置了5分钟缓存 和20分钟缓存
@Configuration public class CacheConfig { @Bean @Primary public CacheManager cacheManager(RedissonClient redissonClient) { Map<String, org.redisson.spring.cache.CacheConfig> configMap = Maps.newHashMap(); org.redisson.spring.cache.CacheConfig config = new org.redisson.spring.cache.CacheConfig(); config.setTTL(60*60*1000); config.setMaxIdleTime(60 * 60 * 1000 * 24); config.setMaxSize(100000); configMap.put(CacheConstant.CACHE_NAME, config); return new RedissonSpringCacheManager(redissonClient, configMap); } @Bean public CacheManager fiveMinRedisCacheManger(RedissonClient redissonClient) { Map<String, org.redisson.spring.cache.CacheConfig> configMap = Maps.newHashMap(); org.redisson.spring.cache.CacheConfig config = new org.redisson.spring.cache.CacheConfig(); config.setTTL(60*5*1000); config.setMaxIdleTime(60 * 60 * 1000); config.setMaxSize(100000); configMap.put(CacheConstant.CACHE_NAME, config); return new RedissonSpringCacheManager(redissonClient, configMap); } @Bean public CacheManager twentyMinRedisCacheManger(RedissonClient redissonClient) { Map<String, org.redisson.spring.cache.CacheConfig> configMap = Maps.newHashMap(); org.redisson.spring.cache.CacheConfig config = new org.redisson.spring.cache.CacheConfig(); config.setTTL(60*20*1000); config.setMaxIdleTime(60 * 60 * 1000); config.setMaxSize(100000); configMap.put(CacheConstant.CACHE_NAME, config); return new RedissonSpringCacheManager(redissonClient, configMap); } }
使用时候的坑:
@Cacheable(cacheManager = "fiveMinRedisCacheManger",cacheNames = SystemConstant.DEFAULT_CACHE_NAME, key = "#root.methodName",unless = "#result.code != 200")
注意
其中condition是对入参进行判断,符合条件的缓存,不符合的不缓存。
其中unless是对出参进行判断,符合条件的不缓存,不符合的缓存。
有点绕,大概意思condition是在方法进入的时候进行判断,unless是在方法执行结束之后进行判断,两个都是在判断是否进行缓存。
condition条件不能使用#result 不然会报SpEL解析错误
conditon文档
/**
*
* Spring 表达式语言 (SpEL) 表达式用于使方法缓存有条件。
* 默认为"" ,表示方法结果始终被缓存。
* SpEL 表达式根据提供以下元数据的专用上下文进行评估:
* #root.method 、 #root.target和#root.caches分别用于对method 、目标对象和受影响缓存的引用。
* 方法名称 ( #root.methodName ) 和目标类 ( #root.targetClass ) 的快捷方式也可用。
* 方法参数可以通过索引访问。例如,可以通过#root.args[1] 、 #p1或#a1访问第二个参数。如果该信息可用,也可以按名称访问参数
*/
String condition() default "";
unless文档
/**
* 用于否决方法缓存的 Spring 表达式语言 (SpEL) 表达式。
* 与condition不同,此表达式在方法被调用后计算,因此可以引用result 。
* 默认为"" ,这意味着缓存永远不会被否决。
* SpEL 表达式根据提供以下元数据的专用上下文进行评估:
* #result用于引用方法调用的结果。对于支持的包装器,例如Optional , #result指的是实际对象,而不是包装器
* #root.method 、 #root.target和#root.caches分别用于对method 、目标对象和受影响缓存的引用。
* 方法名称 ( #root.methodName ) 和目标类 ( #root.targetClass ) 的快捷方式也可用。
* 方法参数可以通过索引访问。例如,可以通过#root.args[1] 、 #p1或#a1访问第二个参数。如果该信息可用,也可以按名称访问参数。
* 自从:3.2
*/
String unless() default "";