使用spring的aop进行redis缓存
redis配置
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
// 建议使用这种方式,小范围指定白名单
ParserConfig.getGlobalInstance().addAccept("cn.com.hatech.auth.server");
// 设置值(value)的序列化采用FastJsonRedisSerializer。
redisTemplate.setValueSerializer(fastJsonRedisSerializer);
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
// 设置键(key)的序列化采用StringRedisSerializer。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
注解RedisCache
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedisCache {
/**
* 0 读 1 写
* @return
*/
int type() default 0 ;
/**
* 默认key
* @return
*/
String key() default "";
/**
* 默认长度 5
* @return
*/
long length() default 5L;
/**
* 默认分钟
* @return
*/
TimeUnit timeunit() default TimeUnit.MINUTES;
}
aop实现
@Component
@Slf4j
@Aspect
public class RedisCacheAspect {
@Resource
private RedisTemplate redisTemplate;
/**
* 定义一个切入点
*/
@Pointcut("execution(* cn.com.hatech.auth.server..*.*(..)) && @annotation(cn.com.hatech.auth.server.cache.RedisCache)")
private void redis() {
}
/**判断一个对象是否是基本类型或基本类型的封装类型*/
private boolean isPrimitive(Object obj) {
try {
return ((Class<?>)obj.getClass().getField("TYPE").get(null)).isPrimitive();
} catch (Exception e) {
return false;
}
}
@Around("redis()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 拦截的方法参数类型
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
// 拦截的实体类,就是当前正在执行的controller
Object target = joinPoint.getTarget();
// 获得被拦截的方法
Method function = target.getClass().getMethod(
joinPoint.getSignature().getName(),
methodSignature.getMethod().getParameterTypes()
);
RedisCache redisCache = function.getAnnotation(RedisCache.class);
// 判断扫描该函数是否包含自定义的log日志注解
if (!function.isAnnotationPresent(RedisCache.class)) {
Object object = joinPoint.proceed();
return object;
}
if (redisCache.type() == 0 && StringUtils.isNotEmpty(redisCache.key())) {
Class<?> returnType = function.getReturnType();
Object o = redisTemplate.opsForValue().get(redisCache.key());
if (ObjectUtils.isEmpty(o)){
// 执行目标方法
Object object = joinPoint.proceed();
redisTemplate.opsForValue().set(redisCache.key(), object, redisCache.length(), redisCache.timeunit());
return object;
}
if (isPrimitive(o)){
return o;
}
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(JSON.parseObject(o.toString()).toJSONString(), returnType);
}
//写
if (redisCache.type() == 1 && StringUtils.isNotEmpty(redisCache.key())) {
// 执行目标方法
Object object = joinPoint.proceed();
redisTemplate.opsForValue().set(redisCache.key(), object, redisCache.length(), redisCache.timeunit());
return object;
}
return null;
}
}
测试
@GetMapping("/test1")
@RedisCache(type = 0,key = "test1_",length=3L,timeunit= TimeUnit.SECONDS)
public int test1(){
return 1;
}