【发布时间】:2020-10-07 09:39:41
【问题描述】:
现有答案很好地解释了如何使用自定义注释进行方法执行时间记录。我想知道是否有办法对 Class 和 Method 使用相同的注解,但是 Pointcut 在使用的地方应该不同。
@LogExecutionTime
public class MyServiceImpl implements MyService {
public void run(){
// logic
}
public void walk(){
// logic
}
private void breather(){
// logic
}
}
如果对类使用注释,则应考虑将类内的所有方法用于 Aspect 类中的执行时间日志记录(如 execution(* com.me.package.MyServiceImpl.*(..)))。但是,如果 Annotation 仅用于类内的单个方法,则还应考虑 Aspect Logging 类中的唯一方法。 (如execution(* com.you.package.YourServiceImpl.forward(..)))。
public class YourServiceImpl implements YourService {
@LogExecutionTime
public void forward(){
// logic
}
@LogExecutionTime
public void backward(){
// logic
}
private void upward(){
// logic
}
}
注解类
package com.myproj.core.utils.annotation;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
@Retention(RUNTIME)
public @interface LogExecutionTime {
}
注释的方面类(使用@kriegaex 建议的切入点)
package com.myproj.core.utils;
import java.time.Duration;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import java.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Aspect class to Log Method Execution time
*/
@Aspect
public class MyMethodExecutionLoggingAspect {
private static final Logger LOG = LoggerFactory.getLogger(MyMethodExecutionLoggingAspect.class);
/**
* This method will log Method Execution Time
*
* @param joinPoint
* @return object
* @throws Throwable
*/
@Around("execution(* (@com.myproj.core.utils.annotation.LogExecutionTime *).*(..)) || execution(@com.myproj.core.utils.annotation.LogExecutionTime * *(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
Instant start = Instant.now();
try {
return joinPoint.proceed();
} finally {
long end = Duration.between(start, Instant.now()).toMillis();
if (end > 0) {
LOG.debug("METHOD EXECUTION TIME LAPSED: {}ms | {}.{}", end, className, methodName);
}
}
}
}
spring.xml中的Spring Bean定义
<bean class="com.myproj.core.utils.MyMethodExecutionLoggingAspect" />
【问题讨论】:
-
你放弃了吗?没有更多的反馈?它仍在我的后续列表中。
-
@kriegaex 抱歉,如前所述,它没有按预期工作。我试图只使用类级别,但不知何故它只记录公共方法。所以现在,我正在使用另一种方法,直接在
@Around中给出方法的限定名称。我肯定会实施这个,但现在它被搁置了。很抱歉给您带来麻烦。 -
我确信我的回答是正确的。我能想到它对你不起作用的唯一原因是你的切入点错误。因为后者正是您在示例代码中隐藏的内容,所以问题暂时结束。我敢肯定,只要您使用具体的切入点更新代码,它就会重新打开。如果我有什么要分析的,我很乐意提供进一步的帮助。
-
感谢@kriegaex,即使我确信这些切入点是正确的,但不知何故它们没有按预期工作。仅供参考,我已经添加了完整的方面类以及您提供的切入点。
-
只是为了确保您没有忘记任何基本内容:如果您使用 Spring AOP,则切面和目标类都必须是
@Components 或声明为@Beans(或更一般地说,必须由 Spring 管理)才能被 Spring AOP 拾取。我在您的代码中看不到任何此类内容。那么原始代码是什么样子的呢?
标签: java spring spring-boot spring-aop