内容参考自以下两个链接
1、springboot中使用AOP切面完成全局日志_aop全局日志_邹飞鸣的博客-CSDN博客
使用AOP记录日志_aop日志_trusause的博客-CSDN博客
第一个链接思路很清晰,讲的也很详细,第二个链接讲了自定义注解
为了便于自己理解做了以下整理
目录
1.aspectj基本概念
2.添加aop依赖
3.进行切面处理
(1)切面类
(2)自定义注解
(3)controller和serviceimpl
4.定义切点时包扫描路径的表达式怎么写
1.aspectj基本概念

下面两个类JoinPoint和ProceedingJoinPoint,ProceedingJoinPoint类在切面类中最后一个方法doAround()中用到了(已注释的部分),用于获取自定义注解

2.添加aop依赖
<!-- aop 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
3.进行切面处理
主要是在切面类中设置切入点(指定包扫描路径),然后定义织入方式(方法前,方法后等)
也可以自定义注解,但是在我看来,最终还是要在切面类指定包扫描路径的,自定义注解无非是传入一些自定义参数,暂时没有探索别的用处
自定义注解的部分已被注释,直接放开注释就能使用
(1)切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
@Aspect
@Component
public class WebLogAspect {
// 获取日志类,方便直接在控制台输出统一格式的日志信息
private final static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
/**
* 以 controller 包下定义的所有请求为切入点
*/
@Pointcut("execution(public * com.tt.test.controller.*.*(..))")
public void webLog() {
}
/**
* 在切点之前织入
*
* @param joinPoint
* @throws Throwable
*/
@Before("webLog()") // webLog():是你@Pointcut注解的方法名
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 开始打印请求日志
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 打印请求相关参数
logger.info("========================================== Start ==========================================");
}
/**
* 在切点之后织入
*
* @throws Throwable
*/
@After("webLog()")
public void doAfter() throws Throwable {
logger.info("=========================================== End ===========================================");
// 每个请求之间空一行
logger.info("");
}
/**
* 环绕
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("webLog()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = proceedingJoinPoint.proceed();
//获取自定义注解中传入的desc
/*Signature signature = proceedingJoinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
EagleEye eagleEye = method.getAnnotation(EagleEye.class);
String desc=eagleEye.desc();
logger.info("Request desc : {}", desc);*/
logger.info("Request Args : {}", Arrays.asList(result).toString());
// 执行耗时
logger.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
return result;
}
}
(2)自定义注解
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface EagleEye {
//描述,默认为空
String desc() default "";
}
(3)controller和serviceimpl
要想serviceimpl中的方法也被aop织入,需要把serviceimpl文件移动到controller文件夹中,因为切面类中定义了包扫描路径,或者不移动文件夹而是在切面类中定义切点的时候把serviceimpl的包路径也包含进去
controller
import com.tt.test.config.EagleEye;
import com.tt.test.service.EagleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试aop全局日志
*/
@RestController
@RequestMapping("/eagle")
public class EagleController {
@Autowired
private EagleService eagleService;
@RequestMapping("/h1")
// @EagleEye(desc = "hello1")
public String h1(){return eagleService.h1();}
@RequestMapping("/h2")
// @EagleEye(desc = "hello2")
public String h2(){return eagleService.h2();}
}
serviceimpl实现类(service层接口省略)
import com.tt.test.config.EagleEye;
import com.tt.test.service.EagleService;
import org.springframework.stereotype.Service;
@Service
public class EagleServiceImpl implements EagleService {
@Override
// @EagleEye(desc = "hello1-service")
public String h1() {
String s="s1";
return s;
}
@Override
// @EagleEye(desc = "hello2-service")
public String h2() {
String s="s2";
return s;
}
}
4.定义切点时包扫描路径的表达式怎么写
