我是否可以使用SpringAOP记录方法的开始和结束,以帮助轻松调试

我是否可以使用SpringAOP记录方法的开始和结束,以帮助轻松调试,spring,spring-aop,Spring,Spring Aop,我使用testNg测试应用程序,并使用SpringTest 我想记录每个方法的开始和结束,以便在发生故障的地方轻松调试 如果我有这样的方法 public void performUserSignIn(){ signInAgent.performSignIn(username,password); } public void performUserSignIn(){ logger.info("started performUsersignI

我使用testNg测试应用程序,并使用SpringTest

我想记录每个方法的开始和结束,以便在发生故障的地方轻松调试

如果我有这样的方法

public void performUserSignIn(){      
     signInAgent.performSignIn(username,password);      
}
public void performUserSignIn(){      
     logger.info("started performUsersignIn");
     signInAgent.performSignIn(username,password);
     logger.info("finished performUsersignIn");      
}
@LogMessage
public void performUserSignIn(){      
     logger.info("started performUsersignIn");
     signInAgent.performSignIn(username,password);
     logger.info("finished performUsersignIn");      
}
我想像这样记录这个方法的开始和结束

public void performUserSignIn(){      
     signInAgent.performSignIn(username,password);      
}
public void performUserSignIn(){      
     logger.info("started performUsersignIn");
     signInAgent.performSignIn(username,password);
     logger.info("finished performUsersignIn");      
}
@LogMessage
public void performUserSignIn(){      
     logger.info("started performUsersignIn");
     signInAgent.performSignIn(username,password);
     logger.info("finished performUsersignIn");      
}
这对于我的测试自动化中的每一种方法来说都是非常麻烦的。我可以使用SpringAOP来实现这一点吗?我的想法是创建一个自定义注释@LogMessage,然后使用它

@LogMessage("performUserSignIn")    
public void performUserSignIn(){      
     logger.info("started performUsersignIn");
     signInAgent.performSignIn(username,password);
     logger.info("finished performUsersignIn");      
}
或者像这样更好

public void performUserSignIn(){      
     signInAgent.performSignIn(username,password);      
}
public void performUserSignIn(){      
     logger.info("started performUsersignIn");
     signInAgent.performSignIn(username,password);
     logger.info("finished performUsersignIn");      
}
@LogMessage
public void performUserSignIn(){      
     logger.info("started performUsersignIn");
     signInAgent.performSignIn(username,password);
     logger.info("finished performUsersignIn");      
}

甚至可以这样做吗?

您需要使用周围的
@建议。示例代码如下所示

@Aspect
public class MethodLogging {

@Around(execution("@annotation(LogMessage)"))
public Object logStartAndEnd(ProceddingJoinPoint pjp){
    String name = pjp.getSignature().getName();
    logger.info("started " + name);
    Object obj = pjp.proceed();
    logger.info("finished " + name); 
    return obj;
}

}

有关更多信息,请参阅相应的java文档。

不要重新发明轮子,因此请查看此处,因为其他人收集了有用的AOP,可在您的项目中立即重用:-)开源是一个伟大的社区:

但是,如果您只寻求自定义快速解决方案,那么在使用Spring时,您可以通过以下方式实现您的需求:

public class MyPerformanceMonitorInterceptor extends AbstractMonitoringInterceptor {

    public MyPerformanceMonitorInterceptor() {
    }

    public MyPerformanceMonitorInterceptor(boolean useDynamicLogger) {
            setUseDynamicLogger(useDynamicLogger);
    }

    @Override
    protected Object invokeUnderTrace(MethodInvocation invocation, Log log) 
      throws Throwable {
        String name = createInvocationTraceName(invocation);
        long start = System.currentTimeMillis();
        log.info("Method " + name + " execution started at:" + new Date());
        try {
            return invocation.proceed();
        }
        finally {
            long end = System.currentTimeMillis();
            long time = end - start;
            log.info("Method "+name+" execution lasted:"+time+" ms");
            log.info("Method "+name+" execution ended at:"+new Date());

            if (time > 10){
                log.warn("Method execution longer than 10 ms!");
            }            
        }
    }
}
配置bean:

@Pointcut("execution(public int com.baeldung.performancemonitor.PersonService.getAge(..))")
public void myMonitor() { }

@Bean
public MyPerformanceMonitorInterceptor myPerformanceMonitorInterceptor() {
    return new MyPerformanceMonitorInterceptor(true);
}

@Bean
public Advisor myPerformanceMonitorAdvisor() {
    AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
    pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.myMonitor()");
    return new DefaultPointcutAdvisor(pointcut, myPerformanceMonitorInterceptor());
}
这将产生:

2017-01-08 19:19:25 INFO PersonService:26 - 
  Method com.baeldung.performancemonitor.PersonService.getAge 
  execution started at:Sun Jan 08 19:19:25 EET 2017
2017-01-08 19:19:25 INFO PersonService:33 - 
  Method com.baeldung.performancemonitor.PersonService.getAge execution lasted:50 ms
2017-01-08 19:19:25 INFO PersonService:34 - 
  Method com.baeldung.performancemonitor.PersonService.getAge 
  execution ended at:Sun Jan 08 19:19:25 EET 2017
2017-01-08 19:19:25 WARN PersonService:37 - 
  Method execution longer than 10 ms!

最后注意:AOP在一些高性能场景中不是最好的选择,但最好考虑“事件中间件”实现……/P>这确实可以使用Spring AOP来完成。看一看SpringDocs,了解更多信息。我认为,若你们是从某处复制,那个么你们应该相信这篇原创文章。而且,这样,OP就有了完整的画面。