基于Aop切面思想对于业务代码的书写记录(巩固使用方法)

前言:在一次开发过程中,需求是 先查询redis缓存,没有再查db,完成一次操作,当时只顾着开发业务,没有时间整理组件的使用,现在空闲下来, 利用 AOP切面来进行 组件的开发,来进行个人经验总结,  AOP思想作用不仅仅是我刚阐述的场景. 这里不阐述AOP的思想,只巩固它的用法.

下面以自身业务代码,进行自我总结梳理.

  1. 添加xml配置
    1.  <!-- 配置注解驱动 --> <mvc:annotation-driven/>
    2. <!--扫描 --><context:component-scan base-package="com.xxx"/>
    3. AOP的 配置 ,这里我使用的 注解标签来实现
    4. 自定义注解类
      /**
       * @Date 2019/10/10 15:42
       * @Created by Z.xh
       * 用于redis操作 表情用于添加注解
       */
      @Target({ElementType.METHOD})
      @Retention(RetentionPolicy.RUNTIME)
      public @interface RedisCacheAnno {
      
          /**
           * key的前缀
           *
           * @return
           */
          String value();
      
          /**
           * key的规则,可以使用springEL表达式,可以使用方法执行的一些参数
           */
          String key();
      }
      

       

    5. aop切面书写

      
      /**
       * @Date 2019/10/10 15:45
       * @Created by Z.xh
       * 用于使用redis 利用aop 存入缓存的操作, 解除代码耦合性
       */
      @Component
      public class RedisCacheAspect {
      
      
          @Autowired
          private RedisTemplate redisTemplate;
      
          // 定义相应的事件
          @Around("cachePointcut()")
          public Object doCache(ProceedingJoinPoint joinPoint) {
              Object object = null;
              try {
                  // 0-1、 当前方法上注解的内容
                  MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                  Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(), signature.getMethod().getParameterTypes());
                  RedisCacheAnno cacheAnnotation = method.getAnnotation(RedisCacheAnno.class);
                  String keyEl = cacheAnnotation.key();
                  String prefix = cacheAnnotation.value();
      
                  // 0-2、 前提条件:拿到作为key的依据  - 解析springEL表达式
                  // 创建解析器
                  ExpressionParser parser = new SpelExpressionParser();
                  Expression expression = parser.parseExpression(keyEl);
                  EvaluationContext context = new StandardEvaluationContext(); // 参数
                  // 添加参数
                  Object[] args = joinPoint.getArgs();
                  DefaultParameterNameDiscoverer discover = new DefaultParameterNameDiscoverer();
                  String[] parameterNames = discover.getParameterNames(method);
                  for (int i = 0; i < parameterNames.length; i++) {
                      context.setVariable(parameterNames[i], args[i].toString());
                  }
                  // 解析
                  String key = prefix + "::" + expression.getValue(context).toString();
                  object = redisTemplate.opsForValue().get(key);
                  if (null != object) {
                      System.out.println("从缓存中获取");
                      // 从缓存中获取
                      return object;
                  }
      
                  // 从数据库中获取
                  object = joinPoint.proceed();
                  System.out.println("从数据库中获取");
      
                  // 存入redis 中
                  redisTemplate.opsForValue().set(key, object);
      
              } catch (Throwable throwable) {
                  throwable.printStackTrace();
              }
              return object;
          }
      }

       

在需要的使用 aop的方法上 贴上相应的注解标签即可,

----------------------------------------------------------------

因为aop 配置也分为2中 一种xml配置, 一种是注解配置,这里只是xml的一种实现方式, 我配置的也是 环绕切面, 在aop本身来说,依然有很多中切面的方式,在这个过程中, 切面表达式也有很多种,需要根据自身的业务需求来配置切面表达式, 最常用的是

execution 表达,需要了解这些的,可以自行百度每一个的作用.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值