SpringBoot自定义注解之实现AOP切面日志详解
通过自定义注解的方式(如:@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() { } /** * 在方法执行前 * @param point * @param myLog * @return */ @Before(value = "pointcut() && @annotation(sysLog)") public void before(SysLog sysLog){ System.out.println("++++执行了before方法++++"); } /** * 在方法执行前后 * @param point * @param myLog * @return */ @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(); } } /** * 方法执行后 * @param joinPoint * @param myLog * @param result * @return */ @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; } /** * 方法执行后 并抛出异常 * @param joinPoint * @param myLog * @param ex */ @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"; }
六、测试
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)