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

综合编程 简书

使用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("nn============================================n"
            + "===errFunc:" + pjp.getSignature()
            + "n===params:" + Arrays.toString(pjp.getArgs())
            + "n============================================n");
            throw throwable;
        }
        long time2 = System.currentTimeMillis();
        logger.info("nn============================================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
    ============================================
简书稿源:简书 (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » 05 使用AOP获取方法调用信息

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录