美文网首页Java高级架构程序员
05 使用AOP获取方法调用信息

05 使用AOP获取方法调用信息

作者: 幽暗金 | 来源:发表于2018-01-13 09:52 被阅读136次

    使用AOP获取服务层方法调用信息

    通过前面章节的学习,相信大家已经对AOP有了一定的了解。
    在这一章节中,将会教大家怎么使用AOP来监控Service层方法的调用,用日志输出调用参数以及方法调用时间等。
    可以方便调试,及性能调优等。

    创建AOP

    1. 切点的选择
      在Spring开发中,服务层一般是放在同一个包里,这个时候我们可以使用这种切点方式:

      execution(* com.learn.service..*(..))
      

      但是不排除某些情况下,服务分散到不同的包中,这个时候我们可以采用另一种方式,通过注解来使用AOP:

      @within(org.springframework.stereotype.Service)
      

      @target(org.springframework.stereotype.Service)
      

      @within和@target的使用可以回顾一下前面的章节

    2. 使用通知
      为了达到可以计算调用服务层方法执行时间的目的,我们在这里可以使用环绕通知的形式,当然,如果不需要计算方法执行时间的话,可以使用前置通知或者后置通知的方式。
      通知的使用可以回顾一下AOP五种通知详解

      private final Logger logger = LoggerFactory.getLogger(this.getClass());
      
      @Around(value = "@target(org.springframework.stereotype.Service)")
      public Object around(ProceedingJoinPoint pjp) throws Throwable {
          Object result;
          long time1 = System.currentTimeMillis();
          try {
              result = pjp.proceed();
          } catch (Throwable throwable) {
              logger.error("\n\n============================================\n"
              + "===errFunc:" + pjp.getSignature()
              + "\n===params:" + Arrays.toString(pjp.getArgs())
              + "\n============================================\n");
              throw throwable;
          }
          long time2 = System.currentTimeMillis();
          logger.info("\n\n============================================\n"
          + "===func:" + pjp.getSignature()
          + "\n===params:" + Arrays.toString(pjp.getArgs())
          + "\n===time:" + (time2-time1) + "ms"
          + "\n===result:" + result
          + "\n============================================\n");
          return result;
      }
      

      到这里,AOP就算写好了,下面我们来测试一下。

    测试

    1. 创建接口

      public interface IHelloService {
          void sayHello();
      
          void say(String msg);
      
          String err(boolean isThrow);
      }
      
    2. 创建其实现类

      @Service
      public class HelloServiceImpl implements IHelloService {
          @Override
          public void sayHello() {
              System.out.println("hello");
          }
      
          @Override
          public void say(String msg) {
              System.out.println(msg);
          }
      
          @Override
          public String err(boolean isThrow) {
              System.out.println("error begin");
              if (isThrow) {
                  throw new RuntimeException("sss");
              }
              return "this is an error";
          }
      }
      
    3. 创建测试用例

      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class ApplicationTests {
      
          @Resource
          private IHelloService helloService;
      
          @Test
          public void test1() {
              helloService.sayHello();
          }
      
          @Test
          public void test2() {
              helloService.say("hello");
          }
      
          @Test
          public void test3() {
              helloService.err(true);
          }
      
          @Test
          public void test4() {
              helloService.err(false);
          }
      
      }
      

      执行test1可以得到结果:

      
      ============================================
      ===func:void com.learn.service.IHelloService.sayHello()
      ===params:[]
      ===time:0ms
      ===result:null
      ============================================
      

      执行test2可以得到结果:

      
      ============================================
      ===func:void com.learn.service.IHelloService.say(String)
      ===params:[hello]
      ===time:0ms
      ===result:null
      ============================================
      

      执行test3可以得到结果:

      
      ============================================
      ===errFunc:String com.learn.service.IHelloService.err(boolean)
      ===params:[true]
      ============================================
      
      
      java.lang.RuntimeException: sss
      ...
      

      执行test4可以得到结果:

      
      ============================================
      ===func:String com.learn.service.IHelloService.err(boolean)
      ===params:[false]
      ===time:0ms
      ===result:this is an error
      ============================================
      

    目录
    源码链接

    相关文章

      网友评论

        本文标题:05 使用AOP获取方法调用信息

        本文链接:https://www.haomeiwen.com/subject/exxcoxtx.html