需求

  最近碰到一个问题,需要对关键操作的入参和返回值进行记录,并不是使用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编程的更多相关文章

  1. springboot的aop编程

    以下内容是模仿杨开振<<深入浅出springboot 2.x>>的4.2章节内容. 开始前,需要先修改pom.xml,加入以下内容 <!-- https://mvnrep ...

  2. SpringBoot学习笔记(七):SpringBoot使用AOP统一处理请求日志、SpringBoot定时任务@Scheduled、SpringBoot异步调用Async、自定义参数

    SpringBoot使用AOP统一处理请求日志 这里就提到了我们Spring当中的AOP,也就是面向切面编程,今天我们使用AOP去对我们的所有请求进行一个统一处理.首先在pom.xml中引入我们需要的 ...

  3. SpringBoot切面Aop的demo简单讲解

    前言 本篇文章主要介绍的是SpringBoot切面Aop的demo简单讲解. SpringBoot Aop 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码. 切面(Aop) 一.概 ...

  4. Spring全家桶——SpringBoot之AOP详解

    Spring全家桶--SpringBoot之AOP详解 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方 ...

  5. 【原】iOS动态性(三) Method Swizzling以及AOP编程:在运行时进行代码注入

    概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...

  6. 基于ASP.NET MVC的热插拔模块式开发框架(OrchardNoCMS)--AOP编程

    AOP编程在目前来说好像是大家都比较喜欢的.ASP.NET MVC中的Filter就是使用AOP实现的配置器模式.AOP在编码中的应用主要有如下几个方面: 日志记录,跟踪,优化和监控 事务的处理 持久 ...

  7. Method Swizzling以及AOP编程:在运行时进行代码注入-备用

    概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...

  8. AOP编程,spring实现及JDK,CGLIB实现

    什么是AOP? AOP(Aspect-OrientedProgramming,面向方面编程)和OOP(Object-Oriented Programing,面向对象编程)思想不同,两者并非对立关系,前 ...

  9. AOP编程和ASP.NET MVC

    AOP编程和ASP.NET MVC AOP(Aspect oriented programming)面向切面编程.说成切面不容易理解,代码哪里有切面?又不是三维物体.概念不管,我们从其思想来理解这个名 ...

随机推荐

  1. ConnectionString属性(网速慢的情况下研究Connect Timeout)

    ConnectionString 类似于 OLE DB 连接字符串,但并不相同.与 OLE DB 或 ADO 不同,如果“Persist Security Info”值设置为 false(默认值),则 ...

  2. css,对包含有子元素的元素进行flex后,会影响原有的布局。如何后续处理

    对包含有子元素的元素进行flex后,会影响原有的布局. 例如设置两个div,第一个div包含一个img(图片),第二个div包含多个p元素(对前面的img的说明).如下图 1:当对着两个两个div进行 ...

  3. js中console.info的使用

    语法:console.info(obj1 [, obj2, ..., objN]);console.info(msg [, subst1, ..., substN]); 参数obj1 ... objN ...

  4. 【vue】vue生命周期---精简易懂-----【XUEBIG】

    主要的生命周期函数分类:    - 创建期间的生命周期函数:(只会调用一次)       + beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属 ...

  5. KVM on CubieTruck 原理以及网络性能相关思考

    1.virtio框架包括哪些? (1)virtio:面向guest驱动的API接口,它在概念上将前端驱动附加到后端驱动,具体实现位于driver/virtio/virtio.c (2)Transpor ...

  6. java-java技术链接

    java基础知识总结大全:https://blog.csdn.net/hao19980724/article/details/83792516 Java核心技术梳理-集合:https://mp.wei ...

  7. 《我是一只IT小小鸟》读书笔记——第七周

    我是一只IT小小鸟,每一个程序员都是从这样的阶段成长起来的,问题是是否能一开始就找到正确的路径,少走弯路.本书收集了许多年轻程序员从大学开始到就业的成长之路,十分有指导价值也很让人深思. 切忌急功近利 ...

  8. idea中log4j的简单使用

    首先,我们需要建立一个 maven 项目 (如果你没有配置maven 请参考https://www.cnblogs.com/PerZhu/p/10714077.html配置) 接下来开始配置 pom. ...

  9. emqx配置ssl

    1.生产自签证书 mkdir /etc/emqttd/certs/ && cd /etc/emqttd/certs/ openssl genrsa -out ca-key.pem 20 ...

  10. 【Docker】docker安装redis

    一.下载镜像并运行容器 1.指定redis.conf配置文件方式运行 docker run -p 6379:6379 --name myredis -v $PWD/conf/redis.conf:/e ...