SpringBoot自定义注解之实现AOP切面日志详解
作者:你是我的小丫小太阳 发布时间:2022-12-18 17:58:06
标签: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";
}
六、测试
来源:https://blog.csdn.net/qq_40083897/article/details/105831925


猜你喜欢
- 本文实例为大家分享了Java流布局图形界面编写代码,供大家参考,具体内容如下package jisuanqi;import java.awt
- 注意事项阿里云的dataworks提供了OpenApi, 需要是企业版或旗舰版才能够调用,也就是付费项目。这里测试主要是调用拉取datawo
- 线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。当线程进入对象的synchronized代
- 首先在layout布局中设置按钮和一个ImageView<Button android:id="@+id/sel
- @Bean修饰的方法参数的注入方法参数默认注入方式为Autowired,即先根据类型匹配,若有多个在根据名称进行匹配。1:复杂类型可以通过@
- 一、spring声明式事务1.1 spring的事务管理器spring没有直接管理事务,而是将管理事务的责任委托给JTA或相应的持久性机制所
- 在 C 语言中,如果发生错误,上级函数要进行出错处理,层层上传,容易造成过多的出错处理代码,并且传递的效率比较低下。C++ 中的异常C++
- 本文实例讲述了Java基于享元模式实现五子棋游戏功能。分享给大家供大家参考,具体如下:一、模式定义享元模式,以共享的方式高效地支持大量的细粒
- 目录概述c#方法概述在微信支付中,当用户支付成功后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。接收微信支付异步
- Java 向上转型和向下转型的详解转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父
- 1. json数据类型类型描述Number数字型String字符串型Boolean布尔型Array数组Object对象null空值(1)js
- 今天把Android Studio 2.3 更新为了3.0 遇到一个蛋疼的问题如图:格式化完代码后发现不会自动换行了,看着真心不爽。后来发现
- 目录前言1.设计模式:单例模式1.1 使用时分配,1.2 声明时实例化1.3 双检锁1.4 .net 特性保证的线程安全1.5 使用DI依赖
- 之前我写过直接用国内镜像的IP地址端口进行配置国内镜像的,如下链接:Android studio配置国内镜像源但是这种方法不一定在每台电脑上
- 一.先说结论针对任何一个代码记录都进行Revert Commit操作:①不管此记录是commit未push,还是已经push过;②不管此记录
- 引言:序列化是将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其带你过去的状态写入到临时或持储存区,反序列化就是重新创
- 根据数据库表名生成实体类公司用的jpa,没有用mybatis。所以也没有用mybatis自动生成。但有些数据库表字段太多,就想着一劳永逸了,
- 去年春节的时候支付宝推行的集福娃活动着实火的不能再火了,更给力的是春晚又可以全民参与咻一咻集福娃活动,集齐五福就可平分亿元大红包,只可惜没有
- starter起步依赖starter起步依赖是springboot一种非常重要的机制,它打包了某些场景下需要用到依赖,将其统一集成到star
- 日期、数字格式化显示,是web开发中的常见需求,spring mvc采用XXXFormatter来处理,先看一个最基本的单元测试:packa