SpringBoot 基于自定义注解的Redis AOP操作

使用Spring的@Cacheable实现Reids缓存时,会遇到过期时间不能直接在注解中赋值的问题,在项目中自己动手实现一个基于注解的RedisCache处理,可以在注解中直接指定Key(键)和Expired(过期时间)。然后AOP拦截,解析注解并做相应处理。

注解定义如下:

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisCache {

    /**
     * 键
     * @return
     */
    String key() default "";

    /**
     * 过期时间
     * @return
     */
    long expired() default -1;

    /**
     * 是否为查询操作
     * 如果为写入数据库的操作,该值需置为 false
     * @return
     */
    boolean read() default true;
}

AOP拦截类如下:

@Component
@Aspect
public class RedisCacheAspect {
    private final static Logger logger = LoggerFactory.getLogger(RedisCacheAspect.class);

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 定义切入点,使用了 @RedisCache 的方法
     */
    @Pointcut("@annotation(RedisCache)")
    public void redisServicePoint(){

    }

    /**
     * 环绕通知,方法拦截器
     */
    @Around("redisServicePoint()")
    public Object WriteReadFromRedis(ProceedingJoinPoint point){
        logger.info("<====== 进入 redisCache 环绕通知 ======>");
        try {
            // 获取RedisCache注解
            RedisCache redisCache = ((MethodSignature)point.getSignature()).getMethod().getAnnotation(RedisCache.class);
            if(redisCache != null && redisCache.read()){
                // 查询操作
                Object obj = redisTemplate.opsForValue().get(redisCache.key());
                if(obj == null){
                    // Redis 中不存在,则从数据库中查找,并保存到 Redis
                    logger.info("<====== Redis 中不存在该记录,从数据库查找 ======>");
                    obj = point.proceed();
                    if(obj != null) {
                        if(redisCache.expired() > 0) {
                            redisTemplate.opsForValue().set(redisCache.key(), obj, redisCache.expired(), TimeUnit.SECONDS);
                        }else {
                            redisTemplate.opsForValue().set(redisCache.key(), obj);
                        }
                    }
                }

                return obj;
            }
        }catch (Throwable ex){
            logger.error("<====== RedisCache 执行异常: {} ======>", ex);
        }

        return null;
    }
}

在查询方法中使用注解:

@RedisCache(key = "test_user", expired = 30000)
public User findById(Long uid) {
    return userMapper.selectByPrimaryKey(uid);
}

这样就实现了一个简单基于AOP的Redis缓存处理过程,该方法可以根据需要进行各种扩展。


你可能感兴趣的:(Spring,Data,Redis)