增加切面依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
增加注解文件
package com.example.fastjson.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
增加切面
package com.example.fastjson.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogExecutionTimeAspect {
private static final Logger logger = LoggerFactory.getLogger(LogExecutionTimeAspect.class);
@Around("@annotation(com.example.fastjson.annotation.LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
return proceed;
}
}
测试
@RestController
@RequestMapping("test")
@Slf4j
public class TestController {
@GetMapping("hello")
@LogExecutionTime
public String hello(){
return "hello";
}
}
在http://localhost:8080/test/hello刷新,控制台显示如下信息
进阶一
增加注解前后执行信息
@Aspect
@Component
public class LogExecutionTimeAspect {
private static final Logger logger = LoggerFactory.getLogger(LogExecutionTimeAspect.class);
@Pointcut("@annotation(com.example.fastjson.annotation.LogExecutionTime)")
public void logExecutionTimePointcut() {}
@Around("logExecutionTimePointcut()")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
return proceed;
}
@Before("logExecutionTimePointcut()")
public void before() {
logger.info("Before executing method with LogExecutionTime annotation");
}
@After("logExecutionTimePointcut()")
public void after() {
logger.info("After executing method with LogExecutionTime annotation");
}
}
进阶二
在class上增加注解,不必每个方法都增加上注解,使用class和方法都可以共用注解
修改LogExecutionTime
增加ElementType.TYPE
完整代码
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
修改LogExecutionTimeAspect
增加@within(com.example.fastjson.annotation.LogExecutionTime)
完整代码
package com.example.fastjson.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogExecutionTimeAspect {
private static final Logger logger = LoggerFactory.getLogger(LogExecutionTimeAspect.class);
@Pointcut("@within(com.example.fastjson.annotation.LogExecutionTime) || @annotation(com.example.fastjson.annotation.LogExecutionTime)")
public void logExecutionTimePointcut() {}
@Around("logExecutionTimePointcut()")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
return proceed;
}
@Before("logExecutionTimePointcut()")
public void before() {
logger.info("Before executing method with LogExecutionTime annotation");
}
@After("logExecutionTimePointcut()")
public void after() {
logger.info("After executing method with LogExecutionTime annotation");
}
}