AOP监控方法的运行时间

之前写过AOP,现在项目需要监控方法的运行时间。这里采用spring aop来统计各个阶段的用时,其中计时器工具为StopWatch。

使用配置文件:
在spring的xml配置文件中:


  
      
      



  

使用AOP时,xml里面别忘了以下配置:


配置完了,接下来实现拦截器:
继承MethodInterceptor接口,使用commons-lang提供的StopWatch

import org.aopalliance.intercept.MethodInterceptor;  
import org.aopalliance.intercept.MethodInvocation;  
import org.apache.commons.lang.StringUtils;  
import org.apache.commons.lang.time.StopWatch;  
import org.apache.commons.logging.Log;  
import org.apache.commons.logging.LogFactory;  
public class MethodTimeAdvice implements MethodInterceptor {  
    protected final Log log = LogFactory.getLog(MethodTimeAdvice.class);     
        
    /**   
     * 拦截要执行的目标方法   
     */    
    public Object invoke(MethodInvocation invocation) throws Throwable {     
        //用 commons-lang 提供的 StopWatch 计时,Spring 也提供了一个 StopWatch     
        StopWatch clock = new StopWatch();     
        clock.start(); //计时开始     
        Object result = invocation.proceed();     
        clock.stop();  //计时结束     
             
        //方法参数类型,转换成简单类型     
        Class[] params = invocation.getMethod().getParameterTypes();     
        String[] simpleParams = new String[params.length];     
        for (int i = 0; i < params.length; i++) {     
            simpleParams[i] = params[i].getSimpleName();     
        }     
             
        log.info("Takes:" + clock.getTime() + " ms ["    
                + invocation.getThis().getClass().getName() + "."    
                + invocation.getMethod().getName() + "("+StringUtils.join(simpleParams,",")+")] ");     
        return result;     
    }     
}  

使用注解:
在spring的xml配置文件中:




    
    
    

切点:

import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.time.StopWatch;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MethodTimeAdvice{

    protected final Log log = LogFactory.getLog(MethodTimeAdvice.class);

    @Pointcut("execution(* com.tmg.perfomance.service.impl.*.*(..))")
    private void serviceMethod() {
    }

    @Around("serviceMethod()")
    public Object logMethodRunningTime(ProceedingJoinPoint pjp) throws Throwable {
        // start stopwatch
        StopWatch watch = new StopWatch();
        watch.start();
        Object retVal = pjp.proceed();
        // stop stopwatch
        watch.stop();
        Long time = watch.getTime();
        String methodName = pjp.getSignature().getName();

        log.info(methodName +" cost : "+ clock.getTime() + " ms")
        return retVal;
    }
}

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/spring/app*.xml","/spring/service/app*.xml"}) //加载配置文件  
public class BaseJunit4Test  {

    @Autowired
    private YourService yourService; //自动注入

    // 测试你需要的方法
    @Test
    public void testYourMethod() {
        yourService.xxxx()
        ...
    }
    
    // 测试方法运行完毕后,做你需要的后续处理
    //@After
    //public void testMethodActive() {
    //  ...
    //}
}

其他:

  • 环绕通知加入多个point
    用||连接多个point

        
            
            
            
        
    

其中,&&,||,可以写成and,or。

  • 监听时间工具StopWatch每次只能启动一个,一定要关闭后才能启动下一个。
    controller开始后执行其他逻辑,然后调用service,这时候service启动定时会失败,因为controller的计时器还没关,因此需要先关掉controller的计时器。这导致controller只计了调用service之前的时间,service返回值之后,controller再进行其他处理的时间并没有被统计。

参考:
http://www.cnblogs.com/liuyitian/p/4101531.html
http://blog.csdn.net/qiutongyeluo/article/details/52468081

你可能感兴趣的:(AOP监控方法的运行时间)