参考书:Spring实战(第4版) Spring Boot 2 精髓
IDE: IDEA 2019.2.3
Maven 3.6.2
Spring Boot 2.1.10.RELEASE
Knife4j
一、准备:
1. 对Spring AOP 有点了解
2. pom中添加aop的starter
如果parent定义了版本,此处可以不加version
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.1.10.RELEASE</version>
</dependency>
二、配置
1. 在启动类添加自动代理注解
@EnableAspectJAutoProxy
2. 编写切面
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StopWatch;
@Configuration
public class GlobalConfig {
@Bean
StopWatch stopWatch(){
return new StopWatch();
}
}
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect {
private static final Logger logger = LoggerFactory.getLogger(Aspect.class);
@Autowired
private StopWatch stopWatch;
@Pointcut(value = "execution(com.tjonecorp.meeting.base.ReturnEntity com.tjonecorp.meeting.controller.*.*(..)) " +
"&& @annotation(org.springframework.web.bind.annotation.GetMapping)" +
"|| @annotation(org.springframework.web.bind.annotation.PostMapping)")
public void getReq() {
// 切点
}
@Around("getReq()")
public Object simplePrintReqProcess(ProceedingJoinPoint pjp) throws Throwable {
// 通知开始时计时
stopWatch.start();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//获取请求的request
HttpServletRequest request = attributes.getRequest();
// 连接点所在类对象
Object o = pjp.getTarget();
// 连接点所在方法
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
Method method = methodSignature.getMethod();
// 输出请求log
logger.info("--------------------------------Request Start--------------------------------");
logger.info("Request URL: {}", request.getRequestURI());
logger.info("Request Method: {}", o.getClass().getName() + "." + method.getName());
Object result = pjp.proceed();
stopWatch.stop();
logger.info("Request done in {}ms", stopWatch.getTotalTimeMillis());
logger.info("--------------------------------Response Success--------------------------------\n");
return result;
}
}
看看效果:
注意:如果不用变量接收 pjp.proceed(),控制器中方法的返回体无法得到,可用swagger测试便知。
以上代码sonar扫描没有大问题,可直接粘贴稍作修改即可。
来源:CSDN
作者:打死一个嘤嘤怪
链接:https://blog.csdn.net/q1779020410/article/details/104772890