记录一次SpringBoot实现AOP编程
需求
最近碰到一个问题,需要对关键操作的入参和返回值进行记录,并不是使用log记录,而是插入到数据库中。
思路:如果采用硬编码,在每个操作后都添加,会产生大量重复代码。因而打算使用自定义注解,通过AOP对注解进行拦截,对有注解的方法进行拦截,下面给出自己Demo的实现。
实现
第一步:导入Maven依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第二步:自定义注解,定义注解的属性。
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RecordRpc {
// 具体路径
String url();
// 数据来源
String dataSource();
// 备注
String remarks();
}
第三步:定义对注解拦截后的具体操作
@Aspect
@Component
public class RecordAnnotationAop { @Autowired
PostService postService; // 声明拦截的注解
@Pointcut("@annotation(ticket.annotation.RecordRpc)")
private void cutMethod() { } // 使用环绕通知,对目标方法进行拦截
@Around("cutMethod()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // 执行拦截的方法
Object proceed = joinPoint.proceed(); // 获取目标方法的名称
String methodName = joinPoint.getSignature().getName();
// 获取方法传入参数
Object[] params = joinPoint.getArgs();
JSONObject obj = new JSONObject();
if (params.length > 0) {
for (int i = 0; i < params.length; i++) {
obj.put("arg[" + i + "]", params[i]);
}
}
System.out.println("AOP入参:" + methodName + obj.toJSONString()); // 获取执行结果
System.out.println("AOP执行结果:");
if (proceed != null) {
System.out.println(JSON.toJSON(proceed));
}
// 获取注解上参数
System.out.println("注解上参数:");
RecordRpc annotation = getDeclaredAnnotation(joinPoint);
System.out.println("url:" + annotation.url());
System.out.println("dataSource:" + annotation.dataSource());
System.out.println("remarks:" + annotation.remarks());
return proceed;
} /**
* 获取方法中声明的注解信息
*
* @param joinPoint
* @return
* @throws NoSuchMethodException
*/
public RecordRpc getDeclaredAnnotation(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
// 获取方法名
String methodName = joinPoint.getSignature().getName();
// 反射获取目标类
Class<?> targetClass = joinPoint.getTarget().getClass();
// 拿到方法对应的参数类型
Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
// 根据类、方法、参数类型(重载)获取到方法的具体信息
Method objMethod = targetClass.getMethod(methodName, parameterTypes);
// 拿到方法定义的注解信息
RecordRpc annotation = objMethod.getDeclaredAnnotation(RecordRpc.class);
// 返回
return annotation;
}
}
第四步:注解使用

结果展示:

大家看明白了吗?如果大家设计api开放接口,在设计鉴权这块的时候 ,也是可以通过自定义注解来完成哦,其核心的思想是将公共的操作抽取出来,也就是面向切面编程的思想。
参考:https://www.cnblogs.com/lingyejun/p/9941350.html
记录一次SpringBoot实现AOP编程的更多相关文章
- springboot的aop编程
以下内容是模仿杨开振<<深入浅出springboot 2.x>>的4.2章节内容. 开始前,需要先修改pom.xml,加入以下内容 <!-- https://mvnrep ...
- SpringBoot学习笔记(七):SpringBoot使用AOP统一处理请求日志、SpringBoot定时任务@Scheduled、SpringBoot异步调用Async、自定义参数
SpringBoot使用AOP统一处理请求日志 这里就提到了我们Spring当中的AOP,也就是面向切面编程,今天我们使用AOP去对我们的所有请求进行一个统一处理.首先在pom.xml中引入我们需要的 ...
- SpringBoot切面Aop的demo简单讲解
前言 本篇文章主要介绍的是SpringBoot切面Aop的demo简单讲解. SpringBoot Aop 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码. 切面(Aop) 一.概 ...
- Spring全家桶——SpringBoot之AOP详解
Spring全家桶--SpringBoot之AOP详解 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方 ...
- 【原】iOS动态性(三) Method Swizzling以及AOP编程:在运行时进行代码注入
概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...
- 基于ASP.NET MVC的热插拔模块式开发框架(OrchardNoCMS)--AOP编程
AOP编程在目前来说好像是大家都比较喜欢的.ASP.NET MVC中的Filter就是使用AOP实现的配置器模式.AOP在编码中的应用主要有如下几个方面: 日志记录,跟踪,优化和监控 事务的处理 持久 ...
- Method Swizzling以及AOP编程:在运行时进行代码注入-备用
概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...
- AOP编程,spring实现及JDK,CGLIB实现
什么是AOP? AOP(Aspect-OrientedProgramming,面向方面编程)和OOP(Object-Oriented Programing,面向对象编程)思想不同,两者并非对立关系,前 ...
- AOP编程和ASP.NET MVC
AOP编程和ASP.NET MVC AOP(Aspect oriented programming)面向切面编程.说成切面不容易理解,代码哪里有切面?又不是三维物体.概念不管,我们从其思想来理解这个名 ...
随机推荐
- ConnectionString属性(网速慢的情况下研究Connect Timeout)
ConnectionString 类似于 OLE DB 连接字符串,但并不相同.与 OLE DB 或 ADO 不同,如果“Persist Security Info”值设置为 false(默认值),则 ...
- css,对包含有子元素的元素进行flex后,会影响原有的布局。如何后续处理
对包含有子元素的元素进行flex后,会影响原有的布局. 例如设置两个div,第一个div包含一个img(图片),第二个div包含多个p元素(对前面的img的说明).如下图 1:当对着两个两个div进行 ...
- js中console.info的使用
语法:console.info(obj1 [, obj2, ..., objN]);console.info(msg [, subst1, ..., substN]); 参数obj1 ... objN ...
- 【vue】vue生命周期---精简易懂-----【XUEBIG】
主要的生命周期函数分类: - 创建期间的生命周期函数:(只会调用一次) + beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属 ...
- KVM on CubieTruck 原理以及网络性能相关思考
1.virtio框架包括哪些? (1)virtio:面向guest驱动的API接口,它在概念上将前端驱动附加到后端驱动,具体实现位于driver/virtio/virtio.c (2)Transpor ...
- java-java技术链接
java基础知识总结大全:https://blog.csdn.net/hao19980724/article/details/83792516 Java核心技术梳理-集合:https://mp.wei ...
- 《我是一只IT小小鸟》读书笔记——第七周
我是一只IT小小鸟,每一个程序员都是从这样的阶段成长起来的,问题是是否能一开始就找到正确的路径,少走弯路.本书收集了许多年轻程序员从大学开始到就业的成长之路,十分有指导价值也很让人深思. 切忌急功近利 ...
- idea中log4j的简单使用
首先,我们需要建立一个 maven 项目 (如果你没有配置maven 请参考https://www.cnblogs.com/PerZhu/p/10714077.html配置) 接下来开始配置 pom. ...
- emqx配置ssl
1.生产自签证书 mkdir /etc/emqttd/certs/ && cd /etc/emqttd/certs/ openssl genrsa -out ca-key.pem 20 ...
- 【Docker】docker安装redis
一.下载镜像并运行容器 1.指定redis.conf配置文件方式运行 docker run -p 6379:6379 --name myredis -v $PWD/conf/redis.conf:/e ...