默认SpringCache是不支持自定义设置TTL的,redis的只支持配置一个统一的TTL,但是这可能并不符合业务的需求。
下面开始增强SpringCache让它支持配置化TTL
定义CachceTTL注解
/**
* 缓存有效时长, 单位: 秒, 若写在类上则类中所有方法都继承此时间
*/
@Target({
ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheTTL {
/**
* 缓存有效时长, 单位: 秒
*/
long value() default -1;
}
实战
缓存
/**
* 生成验证码图片, 返回验证码文字, 并把验证码文字缓存
*/
@CacheTTL(120L)
@CachePut(key = "#token", unless = "#result == null")
public String generateCaptchaImage(String token, OutputStream os) throws IOException {
String captchaText = ImageCaptchaGenerator.generateCaptchaText(candidateString, 4);
ImageCaptchaGenerator.writeCaptchaImageToOutputStream(captchaText, width, height, os);
return captchaText;
}
移除缓存
/**
* 移除缓存
*/
@CacheTTL(120L)
@CacheEvict(key = "#token")
public void removeCaptchaCodeCache(String token) {
}
实现原理
- 使用AOP拦截CacheTTL注解的方法或类里的所有方法
- 在写入redis之前把TTL信息保存到ThreadLocal中
- 在redis写入时取出ThreadLocal中的TTL并设置
Aop拦截并保存TTL
@Component
@Aspect