使用spring的aop进行redis缓存
redis配置
@Configurationpublic 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)@Documentedpublic @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;
}