学习笔记——Spring中的AOP(AspectJ);Spring中AOP概述;Spring中AOP相关术语;AspectJ中切入点表达式;AspectJ中JoinPoint对象;AspectJ中通知
2023-01-18
一、Spring中的AOP
1、AspectJ
(1)简介
Java社区里最完整最流行的AOP框架
在Spring2.0以上版本中,可以使用AspectJ注解或基于XML配置的AOP
(2)使用AspectJ步骤
①在spring核心包的基础上添加支持jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.10</version> </dependency>
②创建spring的配置文件,配置自动扫描的包和AspectJ注解支持
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 开启组件扫描--> <context:component-scan base-package="com.hh"></context:component-scan> <!-- 开启AspectJ注解支持--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
③创建一个类作为切面,在类的上面添加注解
@Component:将当前类标识为一个组件
@Aspect:将当前类标识为切面类(非核心业务提取类)
@Component @Aspect public class MyLogging { /** * 方法之前 */ public static void beforeMethod(String methodName,Object[] arg){ System.out.println("==>Calc中"+methodName+"方法(),参数:"+ Arrays.toString(arg)); } /** * 方法之后 */ public static void afterMethod(String methodName,Object rs){ System.out.println("==>Calc中"+methodName+"方法(),结果:"+rs); } }
④将日志类中的方法添加“通知注解”
@Before
⑤测试
二、Spring中AOP概述
1、AOP:Aspect-Oriented Programming,面向切面编程(面向对象的一种补充)
优势:解决了代码分散与代码混乱的问题
2、OOP:Object-Oriented Programming,面向对象编程
三、Spring中AOP相关术语
1、横切关注点
非核心业务代码
2、切面(Aspect)
将横切关注点提取到类中,这个类称之为切面类
3、通知(Advice)
将横切关注点提取到类之后,横切关注点更名为通知
4、目标(Target)
目标对象,指的是需要被代理的对象(实现类CalcImpl)
5、代理(Proxy)
代理对象可以理解为中介
6、连接点(Joinpoint)
通知方法需要指定通知位置,这个位置称之为连接点(通知之前)
7、切入点(pointcut)
通知方法需要指定通知位置,这个位置称之为切入点(通知之后)
四、AspectJ中切入点表达式
1、语法:@Before(value="execution(权限修饰符 返回值类型 包名.类名.方法名(参数类型))")
2、通配符
(1)【*】
*:可以代表任意权限修饰符&返回值类型
*:可以代表任意包名、任意类名、任意方法名
(2)【..】
.. 代表任意参数类型及参数个数
3、重用切入点表达式
(1)使用@PointCut注解,提取可重用的切入点表达式
//重用切入点表达式 @Pointcut("execution(* com.hh.aop.CalcImpl.*(..))") public void myPointCut(){}
(2)使用方法名()引入切入点表达式
@Before(value = "myPointCut()")
@After("myPointCut()")
五、AspectJ中JoinPoint对象
1、JoinPoint:切入点对象
2、作用:
(1)获取方法名称
String methodName = joinPoint.getSignature().getName();
注:joinPoint.getSignature() 表示方法签名(方法签名=方法名+参数列表)
(2)获取参数
Object[] args = joinPoint.getArgs();
六、AspectJ中通知
1、前置通知
(1)语法:@Before
(2)执行时机:指定方法之前执行
指定方法:即切入点表达式设置位置
注:如果目标方法中有异常,会执行
(3)示例代码
@Before(value = "myPointCut()") public void beforeMethod(JoinPoint joinPoint){ //获取方法名称 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("【前置通知】==>Calc中"+methodName+"方法(),参数:"+ Arrays.toString(args)); }
2、后置通知
(1)语法:@After
(2)执行时机:指定方法所有通知执行之后执行
注:如果目标方法中有异常,会执行
(3)示例代码
@After("myPointCut()") public void afterMethod(JoinPoint joinPoint){ //获取方法名称 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("【后置通知】==>Calc中"+methodName+"方法(),之后执行:"+ Arrays.toString(args)); }
3、返回通知
(1)语法:@AfterReturnning
(2)执行时机:指定方法返回结果时执行
注:@AfterReturnning中returning属性中的的属性名与入参中参数名一致;
如果目标方法中有异常,不执行
(3)示例代码
@AfterReturning(value = "myPointCut()",returning = "rs") public void afterReturnning(JoinPoint joinPoint,Object rs){ //获取方法名称 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("【返回通知】==>Calc中"+methodName+"方法(),返回结果执行!结果:"+ rs); }
4、异常通知
(1)语法:@AfterThrowing
(2)执行时机::指定方法出现异常时执行
注:@AfterThrowing中throwing属性中的的属性名与入参中参数名一致;
如果目标方法中有异常,执行
(3)示例代码
@AfterThrowing(value = "myPointCut()",throwing = "ex") public void afterThrowing(JoinPoint joinPoint,Exception ex){ //获取方法名称 String methodName = joinPoint.getSignature().getName(); //获取参数 Object[] args = joinPoint.getArgs(); System.out.println("【异常通知】==>Calc中"+methodName+"方法(),出现异常时执行!异常:"+ ex); }
说明:
①有异常:前置通知—>异常通知—>后置通知
②无异常:前置通知—>返回通知—>后置通知
5、环绕通知(前四个通知整合)
(1)语法:@Around
(2)作用:整合前四个通知
(3)注意:参数中必须使用ProceedingJoinPoint
(4)示例代码
@Around(value = "myPointCut()") public Object aroundMethod(ProceedingJoinPoint pjp){ //获取方法名称 String methodName = pjp.getSignature().getName(); //获取参数 Object[] args = pjp.getArgs(); //定义返回值 Object rs = null; try { //前置通知 ) System.out.println("【前置通知】==>Calc中"+methodName+"方法(),参数:"+ Arrays.toString(args)); //触发目标对象的目标方法(加减乘除) rs = pjp.proceed(); //返回通知(有异常不执行 System.out.println("【返回通知】==>Calc中"+methodName+"方法(),返回结果执行!结果:"+ rs); } catch (Throwable throwable) { throwable.printStackTrace(); //异常通知 System.out.println("【异常通知】==>Calc中"+methodName+"方法(),出现异常时执行!异常:"+ throwable); }finally { //后置通知(有异常执行) System.out.println("【后置通知】==>Calc中"+methodName+"方法(),之后执行:"+ Arrays.toString(args)); } return rs; }
相关文章
- 微软 Windows 11 KB5007215 补丁发布,修复文件资源管理器操作不跟手问题
- 堪称一站式管理平台,同时支持Linux、MySQL、Redis、MongoDB可视化管理!
- Windows 11迎来新改进!管理应用程序更加便利
- 第三方工具 RoundedTB 可让微软 Windows 11 任务栏变成圆角 UI
- 华为捐赠欧拉 共建数字基础设施开源操作系统
- 微软Office新增实用功能:允许用户在不同设备上轻松送同步字体
- 微软 Visual Studio 2022 正式版发布:升级为 64 位,支持 AI 辅助编程
- Windows 11任务栏设计引发不满!微软将会持续改进
- 超越物理极限!Windows 11出现离奇新Bug:电池充到115%
- Windows 11本月大规模推送 教你一招阻止Windows 10升级
- 微软 Windows11 Dev 预览版出现奇怪 Bug:电量能充到 100% 以上
- 微软将优化Windows 11任务栏:拖动加入等老功能终于回归!
- 微软向发布累积更新KB4023057 以改善Windows Update的可靠性
- 微软 Office Build 20036 安卓预览版推出:新增“鹰眼预览”模式/黑暗模式
- 数据仓库的下一阶段该是什么?
- Windows 11备忘录:你需要知道的有关它的一切
- 面试官:啥?SynchronousQueue是钟?点?房?
- 同样都是开发,为什么你不如别人?
- 可视化搭建平台的参考网格线设计
- 为什么要学习更多的编程语言?同时认为 Go 是最佳