通过自定义注解的方式(如:@SysLog(obj = "操作对象", text = "操作内容"),在 SpringBoot 中来实现 AOP 切面统一打印出入参日志。
一、先看下项目结构
二、Maven JAR依赖
<!-- AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
三、自定义注解
@SysLog
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SysLog {
String obj() default "";
String text() default "";
}
四、AOP切面
import java.lang.reflect.Method;
import com.zxk.demo.annotation.SysLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
@SuppressWarnings("all")
@Aspect
@Component
public class SysLogAspect {
// 切入点
@Pointcut(value = "@annotation(com.zxk.demo.annotation.SysLog)")
private void pointcut() {
}
@Before(value = "pointcut() && @annotation(sysLog)")
public void before(SysLog sysLog){
System.out.println("++++执行了before方法++++");
}
@Around(value = "pointcut() && @annotation(sysLog)")
public Object around(ProceedingJoinPoint point, SysLog sysLog) {
System.out.println("++++执行了around方法++++");
String obj = sysLog.obj();
String text = sysLog.text();
// 拦截的类名
Class clazz = point.getTarget().getClass();
// 拦截的方法
Signature sig = point.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Object target = point.getTarget();
Method currentMethod;
try {
currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
System.out.println("执行了类:" + clazz.getSimpleName());
System.out.println("方法:" + currentMethod.getName());
System.out.println("自定义注解:" + obj+"==="+text);
} catch (Exception e) {
e.printStackTrace();
}
try {
return point.proceed(); // 执行程序
} catch (Throwable throwable) {
throwable.printStackTrace();
return throwable.getMessage();
}
}
@AfterReturning(value = "pointcut() && @annotation(sysLog)", returning = "result")
public Object afterReturning(JoinPoint joinPoint, SysLog sysLog, Object result) {
// HttpServletRequest request = ((ServletRequestAttributes)
// RequestContextHolder.getRequestAttributes()).getRequest();
// HttpSession session = request.getSession();
System.out.println("++++执行了afterReturning方法++++");
System.out.println("自定义注解:" + sysLog.obj()+"=="+sysLog.text());
System.out.println("执行结果:" + result);
return result;
}
@AfterThrowing(value = "pointcut() && @annotation(sysLog)", throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, SysLog sysLog, Exception ex) {
System.out.println("++++执行了afterThrowing方法++++");
System.out.println("请求:" + sysLog.text() + " 出现异常");
}
}
五、Controller层实现
@SysLog(obj = "操作对象", text = "操作内容")
@GetMapping("/index")
public String hello() {
// int num = 5/0;
// System.out.println("执行结果:" + num);
return "hello word";
}
六、测试
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。