需求

  最近碰到一个问题,需要对关键操作的入参和返回值进行记录,并不是使用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. 使用poi调整字体格式、添加单元格注释、自动调整列宽

    1 创建新的工作铺 import java.io.FileOutputStream; import org.apache.poi.hssf.usermodel.HSSFCell; import org ...

  2. 常用正则表达式和一些demo

    一.校验数字的表达式 数字:^[0-9]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数字:^\d{m,n}$ 零和非零开头的数字:^(0|[1-9][0-9]*)$ ...

  3. ImportError: cannot import name Namespace

    运行socketServer报错. 解决: pip uninstall python-socketio pip install python-socketio

  4. spring boot 分布式锁组件 spring-boot-klock-starter

    基于redis的分布式锁spring-boot starter组件,使得项目拥有分布式锁能力变得异常简单,支持spring boot,和spirng mvc等spring相关项目 快速开始 sprin ...

  5. 一个非常有趣的爬虫小练习带ocr识别的

    有个小的想法,想找一找 形近字 .百度一搜索,百度文库有一个,收费4元.而且我觉得字数不是太多.想自己弄一个,于是找到了 这个网站 http://www.fantiz5.com/xingjinzi/ ...

  6. Visual Studio 2012 VC下 OpenGL 配置与使用

    Windows环境下的GLUT下载地址:(大小约为150k)    Download 1 32位Windows环境下安装GLUT的步骤1.将glut.h复制到C:\Program Files (x86 ...

  7. token jwt配置

    1. token jwt配置 1.1. pom <!-- token验证 --> <dependency> <groupId>io.jsonwebtoken< ...

  8. JS-练习题

    1.foo()结果 function foo() { bar.apply(null, arguments); } function bar(){ console.log(arguments); } f ...

  9. HTTP协议学习总结

    一个web应用程序,往往是通过http协议进行前后端通信的.而作为一个web工程师,掌握HTTP协议因此也是Web开发必备的一项技能了,尤其是在工作了一定年限之后,更是深感该知识点的重要性.因此,将以 ...

  10. scrapy随机切换user-agent

    使用github的 scrapy-fake-useragent 不用自己改源码继承自带的userAgent中间件  只需要安装后增加配置即可 https://github.com/alecxe/scr ...