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("\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
    ============================================
    

目录
源码链接

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,506评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 34,627评论 18 399
  • Spring AOP五种通知详解 spring aop通知(advice)分成五类: 前置通知Before adv...
    幽暗金阅读 4,223评论 0 1
  • 一步一步的搭建JAVA WEB项目,采用Maven构建,基于MYBatis+Spring+Spring MVC+B...
    叶子的翅膀阅读 12,897评论 5 25
  • 十一月的共青刮起了寒风 水龙头里的水变得有些刺骨的凉 早上出门看着衣柜发呆 不知道该穿什么 以前总爱在做操的时候抓...
    一颗橙子一颗柚子阅读 203评论 0 0

友情链接更多精彩内容