一、定义注解类TimeLog
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeLog {
String value() default "";
}
二、定义切面AOP类
@Slf4j
@Aspect
@Component
public class TimeLogAspect {
private static final ThreadLocal<Long> firstThreadLocal = new ThreadLocal<>();
private static final ThreadLocal<Long> threadLocal = new ThreadLocal<>();
private static final ThreadLocal<Integer> countThreadLocal = new ThreadLocal<>();
@Pointcut("execution(* *(..)) && @annotation(timeLog )")
public void pointcut(TimeLog timeLog ) {
}
@Around(value = "pointcut(timeLog)", argNames="joinPoint, timeLog")
public Object doAround(ProceedingJoinPoint point, TimeLog timeLog) throws Throwable {
Long startTime = System.currentTimeMillis();
Object result = point.proceed();
Method method = this.getMethod(point);
String methodName = method.toString();
Object[] args = point.getArgs();
EvaluationContext context = this.bindParam(method, args);
Expression expression = parser.parseExpression(timeLog.value());
Object methodDesc= expression.getValue(context);
Long endTime = System.currentTimeMillis();
Long costTime = endTime - startTime;
log.info("methodName: {}, methodDesc: {}, costTime {}ms",methodName,methodDesc,costTime);
return result;
}
private Method getMethod(ProceedingJoinPoint point) throws NoSuchMethodException {
MethodSignature methodSignature = (MethodSignature) point.getSignature();
Method method = methodSignature.getMethod();
Method targetMethod = point.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
return targetMethod;
}
private EvaluationContext bindParam(Method method, Object[] args) {
String[] params = discoverer.getParameterNames(method);
EvaluationContext context = new StandardEvaluationContext();
for (int len = 0; len < params.length; len++) {
context.setVariable(params[len], args[len]);
}
return context;
}
}
三、Aspectj LoadTimeWeaving
1、创建aop.xml配置,放到/src/main/resources/META-INF目录下
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-XnoInline -Xset:weaveJavaxPackages=true -Xlint:ignore -verbose -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
<include within="test..*"/>
</weaver>
<aspects>
<aspect name="xxx.TimeLogAspect"/>
</aspects>
</aspectj>
2、在程序启动时开启agent
@Slf4j
public class MyAspectjAgentInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
@Override
public void initialize(ConfigurableApplicationContext context) {
Instrumentation instrumentation = ByteBuddyAgent.install();
Agent.agentmain("", instrumentation);
InstrumentationSavingAgent.agentmain("", instrumentation);
}
}
3、创建spring.factories,放到/src/main/resources/META-INF目录下
org.springframework.context.context.ApplicationContextInitializer=\
xxx.MyAspectjAgentInitializer
Maven关键依赖
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>1.10.9</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.10.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5</version>
</dependency>
参考
|