后端开发 \ SpringBoot \ Spring AOP 实现监控方法执行的时间(统计service中方法执行的时间)

Spring AOP 实现监控方法执行的时间(统计service中方法执行的时间)

总点击167
简介:版权声明:本文为博主-阿飞(dufyun)-原创文章,未经博主允许可转载,但请标明出处,谢谢!https://blog.csdn.net/u010648555/article/details/50812135

版权声明:本文为博主-阿飞(dufyun)-原创文章,未经博主允许可转载,但请标明出处,谢谢! https://blog.csdn.net/u010648555/article/details/50812135

项目中有时候会遇到统计方法执行的时间,来对项目进行优化!下面是我自己在工作中遇到的问题,和我自己的解决方法。

要统计出项目中方法执行时间大于1秒的那些方法!我们的项目开发使用的是SpringMVC 那么首先想到使用 Aop Aspet 切面统计,那样子更加方便也高效。

1:打开切面!因为项目使用的SpringMVC,项目中的配置文件就配置的 <aop:aspectj-autoproxy proxy-target-class="true"/> ,具体的配置内容如下:

 

<!--自动扫描-->

<context:component-scan base-package="com.dufy">

<context:exclude-filter type="annotation"

expression="org.springframework.stereotype.Controller" />

</context:component-scan>

<!--打开切面-->

<aop:aspectj-autoproxy proxy-target-class="true"/>

<!--支持系统能够识别相应的注解-->

<context:annotation-config></context:annotation-config>


2:开发切面类

 

 

package com.aebiz.b2b2c.webinterface.cart.util;

import org.apache.log4j.Logger;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.Signature;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.springframework.stereotype.Component;

/**

* 使用Aspect统计方法调用的时间

* @author dufy

* @Date 2016-03-02

* @version 1.0

*

*/

@Aspect

@Component

public class LoggingAspect {

//日志记录

public Logger log = Logger.getLogger("reqTime_logger");

/**

* 统计Service中方法调用的时间

* @param joinPoint

* @throws Throwable

*/

@Around("execution(* com.dufy..*Service.*(..))")

public Object logServiceMethodAccess(ProceedingJoinPoint joinPoint) throws Throwable {

long start = System.currentTimeMillis();

Object object = joinPoint.proceed();

long end = System.currentTimeMillis();

long t = end - start;

if(t>=1000){

String tmp = joinPoint.getSignature().toString();

log.info(String.format("class:%s,invoke_time:%s",tmp,t));

}

return object;

}

}

3:声明切面类,因为我上面的配置文件中已经进行全局扫描和支持注解类识别了,这里就不需要再配置对应的类的声明了。

 

 

这样子当项目运行起来的时候,就会

com.dufy..*Service.*(..)

 

这个包下所有的Service中的方法。

具体的execution方法下面进行介绍:

 

 

切点函数execution()的使用

@Around("execution(* *(..))") : execution()是一个切点函数,* * (..)是该函数的参数,其格式为:

<访问权限>? 返回值类型 包名+类名+方法名(参数类型) <throws 异常类型声明>

@Around("execution(* * (..))") //all

@Around("execution(public * * (..))") //绑定方法的访问权限

@Around("execution(public * * (..) throws RuntimeException)") //绑定异常类型声明

@Around("execution(public * * (..) throws RuntimeException+)") //+代表当前类及其子类

@Around("execution(int * (..))") //绑定方法的返回值

@Around("execution(Object+ * (..))") //绑定方法的返回值

@Around("execution(void save* (..))") //绑定方法名,以save开头的方法

@Around("execution(void *m* (..))") //包含m的方法

@Around("execution(void com.dufy.spring.service.*.* (..))") //绑定包名+类名+方法名

@Around("execution(void com.dufy.spring..*Service*.update* (..))") //包名以com.sxt.spring开头的类名中包含Service的类中所有以update开关的方法

@Around("execution(void *())") //绑定方法的参数

@Around("execution(void *(String))") //绑定方法的参数

@Around("execution(void *(..,String,..))") //只要有一个String类型的参数即可

@Around("args(int,String)")

@Around("execution(* save*(..)) || execution(* update*(..))") //切点运算 (||,or,&&,and)

@Around("execution(* save*(..)) or execution(* update*(..))") //切点运算

 

大概就是这些,希望我们举一反三!共同加油!

 

如果在使用的过程中遇到什么问题,欢迎大家可以留言或者通过左侧的联系方式麻烦我,我希望和大家一起成长!

登录后自动展开

意见反馈 常见问题 官方微信 返回顶部