AOP的主要角色

  • 切面:使用切点表达式表示,指定了当前切面逻辑所要包裹的业务模块的范围大小;
  • Advice:也即切面逻辑,指定了当前用于包裹切面指定的业务模块的逻辑

Advice的主要类型

  • @Before:该注解标注的方法在业务模块代码执行之前执行,其不能阻止业务模块的执行,除非抛出异常;
  • @AfterReturning:该注解标注的方法在业务模块代码执行之后执行;
  • @AfterThrowing:该注解标注的方法在业务模块抛出指定异常后执行;
  • @After:该注解标注的方法在所有的Advice执行完成后执行,无论业务模块是否抛出异常,类似于finally的作用;
  • @Around:该注解功能最为强大,其所标注的方法用于编写包裹业务模块执行的代码,其可以传入一个ProceedingJoinPoint用于调用业务模块的代码,无论是调用前逻辑还是调用后逻辑,都可以在该方法中编写,甚至其可以根据一定的条件而阻断业务模块的调用;
  • @DeclareParents:其是一种Introduction类型的模型,在属性声明上使用,主要用于为指定的业务模块添加新的接口和相应的实现。
  • @Aspect:严格来说,其不属于一种Advice,该注解主要用在类声明上,指明当前类是一个组织了切面逻辑的类,并且该注解中可以指定当前类是何种实例化方式,主要有三种:singleton、perthis和pertarget,具体的使用方式后面会进行讲解。

这里需要说明的是,@Before是业务逻辑执行前执行,与其对应的是@AfterReturning,而不是@After,@After是所有的切面逻辑执行完之后才会执行,无论是否抛出异常。

切点表达式

由于Spring切面粒度最小是达到方法级别,而execution表达式可以用于明确指定方法返回类型,类名,方法名和参数名等与方法相关的部件,并且在Spring中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用是最为广泛的。如下是execution表达式的语法:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

这里问号表示当前项可以有也可以没有,其中各项的语义如下:

  • modifiers-pattern:方法的可见性,如public,protected;
  • ret-type-pattern:方法的返回值类型,如int,void等;
  • declaring-type-pattern:方法所在类的全路径名,如com.spring.Aspect;
  • name-pattern:方法名类型,如buisinessService();
  • param-pattern:方法的参数类型,如java.lang.String;
  • throws-pattern:方法抛出的异常类型,如java.lang.Exception;

如下是一个使用execution表达式的例子:

execution(public * com.spring.service.BusinessObject.businessService(java.lang.String,..))

上述切点表达式将会匹配使用public修饰,返回值为任意类型,并且是com.spring.BusinessObject类中名称为businessService的方法,方法可以有多个参数,但是第一个参数必须是java.lang.String类型的方法。上述示例中我们使用了..通配符,关于通配符的类型,主要有两种:

  • *通配符,该通配符主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词。

如下示例表示返回值为任意类型,在com.spring.service.BusinessObject类中,并且参数个数为零的方法:

execution(* com.spring.service.BusinessObject.*())

下述示例表示返回值为任意类型,在com.spring.service包中,以Business为前缀的类,并且是类中参数个数为零方法:

execution(* com.spring.service.Business*.*())
  • ..通配符,该通配符表示0个或多个项,主要用于declaring-type-pattern和param-pattern中,如果用于declaring-type-pattern中,则表示匹配当前包及其子包,如果用于param-pattern中,则表示匹配0个或多个参数。

如下示例表示匹配返回值为任意类型,并且是com.spring.service包及其子包下的任意类的名称为businessService的方法,而且该方法不能有任何参数:

execution(* com.spring.service..*.businessService())

这里需要说明的是,包路径service..*.businessService()中的..应该理解为延续前面的service路径,表示到service路径为止,或者继续延续service路径,从而包括其子包路径;后面的*.businessService(),这里的*表示匹配一个单词,因为是在方法名前,因而表示匹配任意的类。

如下示例是使用..表示任意个数的参数的示例,需要注意,表示参数的时候可以在括号中事先指定某些类型的参数,而其余的参数则由..进行匹配:

execution(* com.spring.service.BusinessObject.businessService(java.lang.String,..))

接下来看一个实例

@Configuration
@Aspect
public class ServiceAspect { private final String ExpGetResultDataPonit = "execution(public * com.mystudy.spring.api.add*(..))"; @Pointcut(ExpGetResultDataPonit)
public void checkParam() {
} @Around("checkParam()")
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
MethodSignature signature = ((MethodSignature) proceedingJoinPoint.getSignature());
System.out.println("环绕通知的目标方法名:" + signature.getName()); //获取参数值
Object[] paranValues = proceedingJoinPoint.getArgs(); for (Object arg : paranValues) {
System.out.println("ARG原来为:" + arg);
if (arg instanceof User) {
User u = (User) arg;
u.setUserName("李四");
}
} return proceedingJoinPoint.proceed(); } }

参考:

https://www.cnblogs.com/zhangxufeng/p/9160869.html
https://blog.csdn.net/puhaiyang/article/details/78146620
https://yq.aliyun.com/articles/652998

Spring AOP 简单应用,对请求参数进行拦截处理的更多相关文章

  1. Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现

    转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...

  2. Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题

    Spring Cloud Gateway 动态修改请求参数解决 # URL 编码错误传参问题 继实现动态修改请求 Body 以及重试带 Body 的请求之后,我们又遇到了一个小问题.最近很多接口,收到 ...

  3. Spring AOP 简单入门笔记 (转)

    分享一个自己写的最为简单的Spring AOP的应用,其实,本人也是学习Spring不久,只是把一些个人的理解分享下,供参考.可能很多人刚开始不太理解到底啥是AOP,其实它也是相对 OOP来说的,类似 ...

  4. 2.5万字长文简单总结SpringMVC请求参数接收

    这是公众号<Throwable文摘>发布的第22篇原创文章,暂时收录于专辑<架构与实战>.暂定下一篇发布的长文是<图文分析JUC同步器框架>,下一篇发布的短文是&l ...

  5. Spring aop 简单示例

    简单的记录一下spring aop的一个示例 基于两种配置方式: 基于xml配置 基于注解配置 这个例子是模拟对数据库的更改操作添加事物 其实并没有添加,只是简单的输出了一下记录 首先看下整个例子的目 ...

  6. Struts2之Action接收请求参数和拦截器

    技术分析之在Struts2框架中使用Servlet的API        1. 在Action类中也可以获取到Servlet一些常用的API        * 需求:提供JSP的表单页面的数据,在Ac ...

  7. spring aop简单日志实例

    转载自:http://www.blogjava.net/laoding/articles/242611.html 一直就用spring的IOC,遗憾spring的另一重要组成部分AOP却没用过,所以近 ...

  8. spring aop简单理解

    aop原理是spring帮我们封装了动态代理,然后我们只管写具体的业务,我们将公共业务也写到具体的一个类中并实现spring为我们提供的对应要连接切入哪个位置的接口,然后再xml中配置它们的关系即可. ...

  9. spring AOP简单入门

    AOP(aspect oriented programming)面向切面编程. 大致意思是在方法的执行过程中织入其他要执行的方法. 项目结构图 先介绍一下通过代理的方式实现aop,几个文件和上一篇一样 ...

随机推荐

  1. delphi 10.3 控件遮挡 webbrowser

    听闻10.3的新特性之一,webbrowser可以被其他控件遮挡, 在等待10.3.1出来后才开始来尝鲜, 但在webbrowser上添加控件后, 发现控件还是被挡住了, 研究发现需要将控件的cont ...

  2. LTE抛弃了CDMA?

    原文链接:https://blog.csdn.net/readhere/article/details/82764919 本文节选自<LTE教程:结构与实施> 大家都听说过这样的说法:LT ...

  3. JS循环结构

    什么是循环结构? 反复一遍又一遍做着相同(相似)的事情 循环结构的两大要素? 循环条件:什么时候开始,什么时候结束 循环操作:循环体,循环过程中 做了什么 一.while语句 while语句 属于前测 ...

  4. 使用HTML和CSS来实现为文字设置图片底纹

    先看一下最终实现的效果 图中的hello是文本而不是图片 那么如何实现这种效果呢? HTML部分: 创建一个h1标签 ,标签内容为(hello).通过link标签链接外部样式表style.css. s ...

  5. margin属性以及垂直外边距重叠问题

       盒子的margin属性         盒子的外边距margin 指的是当前盒子与其他盒子之间的距离,环绕在盒子周围的空白区域,属于不可见的区域,,不会影响到可见框的大小,而是会影响到盒子的位置 ...

  6. ASP.NET超大文件上传与下载

    总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...

  7. luogu 4004 Hello world! 分块 + 并查集 + 乱搞

    其实呢,我也不理解这道题咋做,等以后有时间再研究研究 #include <bits/stdc++.h> #define ll long long #define maxn 100002 u ...

  8. [CSP-S模拟测试]:集合论(模拟)

    题目传送门(内部题73) 输入格式 输入文件$jihe.in$ 第一行一个整数$m$,表示操作的次数. 接下来$m$行,每行描述一个操作. 每行的开始都是一个数字,$1,2,3,4$依次代表$unio ...

  9. linux 文件相关常用命令

    文件或者目录操控命令 1,cd切换目录. 其中- 代表前一个目录 2,mkdir 新建目录. 加上-p参数可以递归创建多级目录 mkdir -p test1/test2/test3 3,rmdir删除 ...

  10. SpringBoot设置SORS的几种方式

    1. 原生支持 Application 启动类添加以下代码: import org.springframework.context.annotation.Bean;import org.springf ...