使用spring的aop进行redis缓存

redis配置

  1. @Configuration
  2. public class RedisConfiguration {
  3. @Bean
  4. public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  5. RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
  6. redisTemplate.setConnectionFactory(redisConnectionFactory);
  7. FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
  8. // 建议使用这种方式,小范围指定白名单
  9. ParserConfig.getGlobalInstance().addAccept("cn.com.hatech.auth.server");
  10. // 设置值(value)的序列化采用FastJsonRedisSerializer。
  11. redisTemplate.setValueSerializer(fastJsonRedisSerializer);
  12. redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
  13. // 设置键(key)的序列化采用StringRedisSerializer。
  14. redisTemplate.setKeySerializer(new StringRedisSerializer());
  15. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  16. redisTemplate.afterPropertiesSet();
  17. return redisTemplate;
  18. }
  19. }

注解RedisCache

  1. @Target({ElementType.PARAMETER, ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface RedisCache {
  5. /**
  6. * 0 读 1 写
  7. * @return
  8. */
  9. int type() default 0 ;
  10. /**
  11. * 默认key
  12. * @return
  13. */
  14. String key() default "";
  15. /**
  16. * 默认长度 5
  17. * @return
  18. */
  19. long length() default 5L;
  20. /**
  21. * 默认分钟
  22. * @return
  23. */
  24. TimeUnit timeunit() default TimeUnit.MINUTES;
  25. }

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;
}