Spring 中缓存注解的使用
CacheAnnotation
在 SpringBoot 中使用缓存注解, 其原理是借助于 AOP (动态代理) 对目标方法进行增强。
@CacheConfig
抽取缓存的公共配置, 只能在类上声明。方法上的同名属性会覆盖类上的配置。
@Cacheable
在调用方法之前,首先在缓存中查找方法的返回值,如果存在,直接返回缓存中的值,否则执行该方法,并将返回值保存到缓存中
和 @CachePut 联合使用时, 会强制读取数据库中的数据
value/cacheNames: 该属性值必须提供,用于指定缓存组的名字,可以指定多个缓存组名称
key: 缓存数据使用的 key, 一条数据的名称由缓存组和 key 所组成,不指定 key 则默认是使用方法参数的值,该属性值支持SpEL表达式 (详情可查阅源码注释)
keyGenerator: 可为空, 指定 key 名称生成器, 当 key 属性未设置时根据生成器规则生成缓存的 key
cacheManager: 可为空, 指定缓存管理器, 用于创建 cacheResolver
cacheResolver: 可为空, 指定获取解析器, 不能与 cacheManager 同时设置
condition:可为空, 指定符合条件的情况下才启用缓存, 当判断结果为 false 时该缓存注解将不启用, 支持SpEL表达式
unless: 可为空, 指定是否不保存缓存, 当判断结果为 true 时将放弃对返回值进行缓存
sync: 默认值为 false, 指定是否以同步的方式操作目标缓存
@CachePut
执行目标方法,并将返回值进行缓存
@CacheEvict
删除指定的缓存数据
allEntries: 默认值为 false, 是否删除缓存组中所有的 key, 为 true 时, 注解中将不能设置 key 属性
beforeInvocation: 默认值为 false, 是否在方法执行器删除缓存数据, 当为 true 时无论方法是否成功执行, 都会删除缓存数据
@CacheIng
分组注解, 可以在该注解中声明 cacheable, CachePut 和 CacheEvict 属性
SpEL
root.method
引用目标方法对象
root.target
引用目标执行对象
root.caches
引用受影响的缓存
root.methodName
引用目标方法名称
root.targetClass
引用目标执行对象类名
root.args[1], #p1, #a1
引用参数列表中的第 2 个参数, 或者使用 #参数名
result
引用返回值对象
注解功能实现
以下代码可以实现与 @Cacheable 相同效果的缓存功能 (需要先配置 Redis 数据源), 同理 @CachePut, @CacheEvict 原理也大致相同。
package com.xtyuns.config;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Aspect
@Component
public class CacheAspect {
@Autowired
private RedisTemplate