第05章 AOP细节
第05章 AOP细节
通过表达式的方式定位一个或多个具体的连接点。
①切入点表达式的语法格式
execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表])) |
②举例说明
表达式 |
execution(* com.atguigu.spring.ArithmeticCalculator.*(..)) |
含义 |
ArithmeticCalculator接口中声明的所有方法。 第一个"*"代表任意修饰符及任意返回值。 第二个"*"代表任意方法。 ".."匹配任意数量、任意类型的参数。 若目标类、接口与该切面类在同一个包中可以省略包名。 |
表达式 |
execution(public * ArithmeticCalculator.*(..)) |
含义 |
ArithmeticCalculator接口的所有公有方法 |
表达式 |
execution(public double ArithmeticCalculator.*(..)) |
含义 |
ArithmeticCalculator接口中返回double类型数值的方法 |
表达式 |
execution(public double ArithmeticCalculator.*(double, ..)) |
含义 |
第一个参数为double类型的方法。 ".." 匹配任意数量、任意类型的参数。 |
表达式 |
execution(public double ArithmeticCalculator.*(double, double)) |
含义 |
参数类型为double,double类型的方法 |
③在AspectJ中,切入点表达式可以通过 "&&"、"||"、"!"等操作符结合起来。
表达式 |
execution (* *.add(int,..)) || execution(* *.sub(int,..)) |
含义 |
任意类中第一个参数为int类型的add方法或sub方法 |
切入点表达式通常都会是从宏观上定位一组方法,和具体某个通知的注解结合起来就能够确定对应的连接点。那么就一个具体的连接点而言,我们可能会关心这个连接点的一些具体信息,例如:当前连接点所在方法的方法名、当前传入的参数值等等。这些信息都封装在JoinPoint接口的实例对象中。
- 在具体的连接点上要执行的操作。
- 一个切面可以包括一个或者多个通知。
- 通知所使用的注解的值往往是切入点表达式。
- 前置通知:在方法执行之前执行的通知
- 使用@Before注解
- 后置通知:后置通知是在连接点完成之后执行的,即连接点返回结果或者抛出异常的时候
- 使用@After注解
- 返回通知:无论连接点是正常返回还是抛出异常,后置通知都会执行。如果只想在连接点返回的时候记录日志,应使用返回通知代替后置通知。
- 使用@AfterReturning注解
- 在返回通知中访问连接点的返回值
- 在返回通知中,只要将returning属性添加到@AfterReturning注解中,就可以访问连接点的返回值。该属性的值即为用来传入返回值的参数名称
- 必须在通知方法的签名中添加一个同名参数。在运行时Spring AOP会通过这个参数传递返回值
- 原始的切点表达式需要出现在pointcut属性中
- 异常通知:只在连接点抛出异常时才执行异常通知
- 将throwing属性添加到@AfterThrowing注解中,也可以访问连接点抛出的异常。Throwable是所有错误和异常类的顶级父类,所以在异常通知方法可以捕获到任何错误和异常。
- 如果只对某种特殊的异常类型感兴趣,可以将参数声明为其他异常的参数类型。然后通知就只在抛出这个类型及其子类的异常时才被执行
- 环绕通知是所有通知类型中功能最为强大的,能够全面地控制连接点,甚至可以控制是否执行连接点。
- 对于环绕通知来说,连接点的参数类型必须是ProceedingJoinPoint。它是 JoinPoint的子接口,允许控制何时执行,是否执行连接点。
- 在环绕通知中需要明确调用ProceedingJoinPoint的proceed()方法来执行被代理的方法。如果忘记这样做就会导致通知被执行了,但目标方法没有被执行。
- 注意:环绕通知的方法需要返回目标方法执行之后的结果,即调用 joinPoint.proceed();的返回值,否则会出现空指针异常。
2)、测试一个环绕+一个普通切面优先级
环绕测试之前将LogUtils的@Component先注释掉防止前四种通知的影响
若与之前四种通知混在一起
新的顺序:
环绕前置--普通前置--目标方法执行(环绕反射控制)--环绕正常返回/出现异常--环绕后置====普通后置===普通返回/异常
注意:普通异常默认会被环绕异常吃掉,
若想在普通通知中拿到异常,需要在环绕catch将异常e抛出【捕获的同时将其抛出】
3.7 重用切入点定义
- 在编写AspectJ切面时,可以直接在通知注解中书写切入点表达式。但同一个切点表达式可能会在多个通知中重复出现。
- 在AspectJ切面中,可以通过@Pointcut注解将一个切入点声明成简单的方法。切入点的方法体通常是空的,因为将切入点定义与应用程序逻辑混在一起是不合理的。
- 切入点方法的访问控制符同时也控制着这个切入点的可见性。如果切入点要在多个切面中共用,最好将它们集中在一个公共的类中。在这种情况下,它们必须被声明为public。在引入这个切入点时,必须将类名也包括在内。如果类没有与这个切面放在同一个包中,还必须包含包名。
- 其他通知可以通过方法名称引入该切入点
- 在同一个连接点上应用不止一个切面时,除非明确指定,否则它们的优先级是不确定的。
- 切面的优先级可以通过实现Ordered接口或利用@Order注解指定。
- 实现Ordered接口,getOrder()方法的返回值越小,优先级越高。
- 若使用@Order注解,序号出现在注解中
默认按照普通切面类的首字母排序,进入
1)、测试一个普通切面+一个普通切面
[LogUtils-前置]【add】方法开始执行,用的参数列表【[1, 2]】
[Vaspect-前置]【add】方法开始执行,用的参数列表【[1, 2]】
[Vaspect-后置]【add】方法最终结束了
[Vaspect-返回]【add】方法正常执行完成,计算结果是:3
[LogUtils-后置]【add】方法最终结束了
[LogUtils-返回]【add】方法正常执行完成,计算结果是:3
先进来的后出去,后进来的先出去【相当于大环LogUtils套小环Vaspect套目标方法】
那么谁先进来看该切面类的类名字母排序L先于V
第05章 AOP细节的更多相关文章
- 异步编程系列第05章 Await究竟做了什么?
p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...
- 第6章 AOP与全局异常处理6.1-6.4 慕课网微信小程序开发学习笔记
第6章 AOP与全局异常处理 https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第3章.AOP技术
第3章--AOP技术 Spring框架 - AOP概述 笔记https://my.oschina.net/hava/blog/758873Spring框架 - AOP使用 笔记https://my.o ...
- 第6章 AOP与全局异常处理6.5-6.11 慕课网微信小程序开发学习笔记
https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 固有的处理异常的思维模式与流 ...
- 第04章 AOP概述
第04章 AOP概述 1.AOP概述 ●AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对传统 OOP(Object-Oriented Progra ...
- 第03章 AOP前奏
第03章 AOP前奏 提出问题 ●情景:数学计算器 ●要求 ①执行加减乘除运算 ②日志:在程序执行期间追踪正在发生的活动 ③验证:希望计算器只能处理正数的运算 ●常规实现 ●问题 ○代码混乱:越来越多 ...
- 第05章 MySQL排序与分页
第05章 MySQL排序与分页 1. 排序数据 1.1 排序规则 使用 ORDER BY 子句排序 ASC(ascend): 升序 DESC(descend):降序 ORDER BY 子句在SELEC ...
- suse 12 二进制部署 Kubernetets 1.19.7 - 第05章 - 部署kube-nginx
文章目录 1.5.部署kube-nginx 1.5.0.下载nginx二进制文件 1.5.1.编译部署nginx 1.5.2.配置nginx.conf 1.5.3.配置nginx为systemctl管 ...
- AspectJ和AOP细节
AspectJ1. 简介 AspectJ:Java社区里最完整最流行的AOP框架.(在Spring中AOP是一种思想,而AspectJ是一种AOP的更明确具体实现) 在Spring2.0以上版本中,可 ...
随机推荐
- 6,Stack
一,Stack简介 Stack是栈.它的特性是:先进后出(FILO, First In Last Out). java工具包中的Stack是继承于Vector(矢量队列)的,由于Vector是通过数组 ...
- 无法启用web调试服务器
场景:vs2005 webservice 项目属性中:web : 使用IIS web 服务器 http://localhost/WSMA --- >自动创建虚拟目录 点击调试的时候F ...
- Harbor修改暴露端口
把原来的端口映射改成1180 一 修改docker-compose.yml [root@topcheer ~]# cat /mnt/harbor/docker-compose.yml version: ...
- MySQL server has gone away 问题解决方法
问题描述: SQLyog在执行大的sql文件时候,报错,报错日志显示2006 - MySQL server has gone away 解决办法: 在php.ini配置文件的[mysqld]节点下添加 ...
- [APIO2013]道路费用
题目描述 幸福国度可以用 N 个城镇(用 1 到 N 编号)构成的集合来描述,这些城镇 最开始由 M 条双向道路(用 1 到 M 编号)连接.城镇 1 是中央城镇.保证一个 人从城镇 1 出发,经过这 ...
- 表单修饰符 number、trim、lazy
number修饰符 <input type="number" v-model.number="age"> 结论:age 类型则为number,非字符 ...
- Vagrant 手册之 Vagrantfile - 提示及技巧
原文地址 Vagrantfile 是一种非常灵活的配置格式.语法基于 Ruby,可以用它做很多事情.在本页使用一些提示和技巧时,请注意正确使用它们. 1. 使用循环定义虚拟机 如果你想对多机器应用稍微 ...
- 【ABAP系列】SAP LSWM处理时,网络中断,出现错误
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP LSWM处理时,网络中断 ...
- github编程类书籍
https://github.com/justjavac/free-programming-books-zh_CN
- github信息安全开源课
尽可能的减少信息差:兄弟们,该知足了,这些资源非常的宝贵了. ### github探索-主题-令人敬畏的名单 令人敬畏的名单: https://github.com/topics/awesome 进入 ...