我使用testNg测试应用程序并使用SpringTest。
我想记录每个方法的开始和结束,以便我可以轻松调试失败发生的地方
如果我有这样的方法
public void performUserSignIn(){
signInAgent.performSignIn(username,password);
}
我希望像这样记录此方法的开始和结束
public void performUserSignIn(){
logger.info("started performUsersignIn");
signInAgent.performSignIn(username,password);
logger.info("finished performUsersignIn");
}
对于我的测试自动化中的每个方法来说,这非常麻烦。我可以使用Spring AOP实现这一目标吗?我的想法是创建一个自定义注释@LogMessage,然后将其用作
@LogMessage("performUserSignIn")
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");
}
甚至可以这样做吗?
答案 0 :(得分:1)
您需要使用@Around
建议。示例代码应如下所示
@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文档。
答案 1 :(得分:0)
不要重新发明轮子,所以请看其他人收集有用的AOP,以便在你的项目中重复使用:-))开源是一个很好的社区:https://github.com/jcabi/jcabi-aspects
但如果您只想寻找自定义快速解决方案,那么在使用Spring时您可以通过以下方式满足您的要求:
pushd
call sejda.bat ...
popd
配置bean:
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!");
}
}
}
}
将产生:
@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());
}
最后注意:AOP在某些高性能场景中不是最佳选择,但最好考虑“事件中间件”实现......