项目-无侵入代码方式使用Redis实现缓存功能

一,情景介绍

公司新需求,在查询接口的manager层要加入redis缓存,只要通过manager层的增删改查方法,统统进行缓存处理。

基于这个需求,我写了一个aop切面,具体实现逻辑如下

ProceedingJoinPoint的操作见文章:https://www.cnblogs.com/draymond/p/12670123.html

二,思路梳理

大致分为以下几个步骤,不多,很简单

  • 自定义注解,凡是在Manager层加该注解的方法,都要进行缓存
  • aop切面,切该注解
  • 判断操作类型(增删改查),得到key值
  • 对操作结果进行缓存

三,代码实践

1,自定义注解

@Target({
   
   ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)//选择运行环境
public @interface E2eCache {
   
   

    //查询条件(查询详情的主键)
    String key();

    /**
     * 方法操作
     * 默认为查询操作 新增指定为[add] 更新指定为[edit] 删除指定为[del] 查询指定为[get]
     * @return
     */
    String operate() default "get";
}

2,切面类

/**
 * 	redis在manager层的切面类,作为缓存机制,达到以下目的
 *      1,判断当前环境是否存在redis,如果存在,则加载缓存机制,如果不存在,则按原逻辑进行
 *      2,增删改查均加入redis缓存
 *      3,考虑对原有代码不侵入的原则
 */
@Aspect
@Component
public class ManagerAspect {
   
   

    @Value("spring.redis.host")
    private String redisHost;

    //TODO 模拟redis缓存,调试通过放RedisTemplate
    private static Map<String,Object> redisTemplate=new HashMap<>();

    private Logger logger= LoggerFactory.getLogger(ManagerAspect.class);

    @Pointcut("@annotation(com.dayouzc.rediscache.annotation.E2eCache)")
    private void cutMethod(){
   
   

    }


    @Around("cutMethod()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
   
   
        //取注解的操作值
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //判断当前方法是否是在Manager类中
        // todo 目前暂时是通过判断当前类是否存在@Repository注解,以及方法名是否包含Manager字符串
        Class<?> declaringClass = signature.getMethod().getDeclaringClass();
        String declaringClassName = declaringClass.getName();
        //如果该方法不是在Manager类,不缓存
        if(!declaringClass.isAnnotationPresent(Repository.class) || !declaringClassName.contains("Manager")){
   
   
            return joinPoint.proceed();
        }
        // 1,判断是否存在redis环境
        if(StringUtils.isBlank("test")){
   
   
            logger.info("======== 当前环境redis不存在,缓存机制失效 ==========");
            //原逻辑处理
            return joinPoint.proceed();
        }else{
   
   
            logger.info("======== 当前环境redis正常,开启Manger层缓存 ==========");
            //得到request请求
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            //2,走redis缓存

            E2eCache annotation = signature.getMethod().getAnnotation(E2eCache.class);
            //操作类型
            String operate = annotation.operate();
            //key的名称
            String id = annotation.key();
            //方法名
            String methodName = joinPoint.getSignature().getName();
            //原方法返回值类型
            Class returnType = signature.getReturnType();
            if(operate.equals("get")){
   
   
                //查询详情
                JSONObject jsonObject = getByArgs(joinPoint, request);
                //根据返回值类型返回对应的实体对象
                Object object = JSONObject.toJavaObject(jsonObject, returnType);
                return object;
            }else if(operate.equals("add")){
   
   
                //新增
                JSONObject jsonObject = addOperation(joinPoint, request);
                Object object = JSONObject.toJavaObject(jsonObject, returnType);
               
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值