Spring之面向切面编程(AOP)
简介
1、什么叫做面向切面编程?
概念:把一个个的横切关注点(某种业务的实现代码)放到某个模块中去,称之为切面。每个切面影响业务的一种功能,切面的目的就是为了功能增强,将需要增强的方法做成切面,实现对业务的增强,就是面向切面编程。
目的:将与业务本身无关,却被业务模块所共同调用的功能代码封装成切面,以减少系统的重复代码,降低耦合,提高可扩展性。
优势:把多个方法前/后的共同代码抽离出来,使用动态代理机制来控制,先执行抽离出来的代码,再执行每一个真实方法.
2、Spring中的AOP使用动态代理来实现:
如果一个类实现了接口,那么spring就使用JDK的动态代理完成AOP;
如果一个类没有实现接口,那么spring就是用cglib完成AOP。
3、AOP的一些基本概念
Joinpoint:连接点,被拦截到需要被增强的方法。去哪里做增强
Pointcut:切入点,哪些包中的哪些类中的哪些方法,可认为是连接点的集合。去哪些地方做增强
Advice:增强,当拦截到Joinpoint之后,在方法执行的什么时机(when)做什么样(what)的增强。
Aspect:切面,Pointcut+Advice,去哪些地方+在什么时候+做什么增强
Weaving:织入,把Advice加到Target上之后,创建出Proxy对象的过程。
切入点语法
1、execution(<访问修饰符>?<返回值类型><声明类型>?<方法名>(<参数名>)<异常名>)
?表示出现0次或1次
通配符:
* :匹配任何部分,只能表示一个单词
.. : 可用于全限定名中和方法参数中,分别表示子包和0到N个参数
2、实例介绍:
XML方式实现AOP
1、导入依赖
spring-aop spring-aspectj
2、命名空间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd ">
</beans>
3、配置AOP
<!--配置AOP--> <aop:config> <!--配置切入点pointcut 哪些包里的哪些类需要被增强 --> <aop:pointcut id="pointcut" expression="execution( * com.test.class03_AOP_xml.service.IUserService.*(..))"/> <!--配置切面Aspect Aspect=pointcut+Advice --> <aop:aspect ref="txManager"> <!--前置增强--> <aop:before method="begin" pointcut-ref="pointcut"/> <!--后置增强--> <aop:after-returning method="commit" pointcut-ref="pointcut"/> <!--异常增强--> <aop:after-throwing method="rollback" pointcut-ref="pointcut"/> <!--最终增强--> <aop:after method="destroy" pointcut-ref="pointcut"/> </aop:aspect> </aop:config>
4、AOP中几个不同的增强时机:
aop:before(前置增强):在方法执行之前执行增强;
aop:after-returning(后置增强):在方法正常执行完成之后执行增强;
aop:after-throwing(异常增强):在方法抛出异常退出时执行增强;
aop:after(最终增强):在方法执行之后执行,相当于在finally里面执行;可以通过配置throwing来获得拦截到的异常信息
aop:around(环绕增强):最强大的一种增强类型。
环绕增强可以在方法调用前后完成自定义的行为,环绕增强有两个要求
1、方法要返回一个Object(返回的结果)
2、方法的第一个参数是ProceedingJoinPoint(可以继续向下传递的切入点)
<!--环绕增强--> <aop:around method="around" pointcut-ref="pointcut"/>
5、代码示例
public class TxManager { public void begin() { System.out.println("开启事务###"); } public void commit() { System.out.println("提交事务++++++"); } public void rollback() { System.out.println("回滚事务...."); } public void destroy() { System.out.println("释放资源……………………"); } //环绕增强代码示例 public Object around(ProceedingJoinPoint pjp){ Object obj=null; try { System.out.println("开启事务###"); obj=pjp.proceed(); System.out.println("提交事务++++++"); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("回滚事务...."); }finally { System.out.println("释放资源……………………"); } return obj; } }
6、获取增强的参数
1.在增强方法中获取异常的信息。
<aop:after-throwing>的标签中添加throwing=“ex”的属性
增强方法rollback中,添加形式参数:Exception ex。
则形参ex中就自动注入了异常对象。 注意:throwing属性的值,必须与方法中形参的名字相同
2.在增强方法中,获取被增强方法的信息
Spring AOP提供org.aspectj.lang.JoinPoint类作为增强方法的第一个参数。
JoinPoint :提供访问当前被增强方法的真实对象、代理对象、方法参数等数据。
ProceedingJoinPoint:JinPoint子类,只用于环绕增强中,可以处理被增强方法。
jp.getThis():获取代理对象
jp.getTarget():获取目标对象
jp.getArgs():获取被增强方法的参数
jp.getSignature():获取被增强方法的参数
注解方式实现AOP
1、命名空间
2、添加注解解析器<aop:aspect-autoproxy/>
3、@Aspect 切面,下面的注解都在切面里配置
@before
@AfterReturning
@AfterThrowing
@After
@Around
4、代码示例
@Aspect public class TxManager { @Pointcut("execution( * com.test.class04_AOP_Anno.service.IUserService.*(..))") public void tt(){} @Before("tt()") public void begin() { System.out.println("开启事务###"); } @AfterReturning("tt()") public void commit() { System.out.println("提交事务++++++"); } @AfterThrowing(value="tt()",throwing = "ex") public void rollback() { System.out.println("回滚事务...."); } @After("tt()") public void destroy() { System.out.println("释放资源……………………"); } @Around("tt()") public Object around(ProceedingJoinPoint pjp){ Object obj=null; try { System.out.println("开启事务###"); obj=pjp.proceed(); System.out.println("提交事务++++++"); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("回滚事务...."); }finally { System.out.println("释放资源……………………"); } return obj; } }
原文地址:https://www.cnblogs.com/xfdhh/p/11488179.html
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- R语言线性模型臭氧预测: 加权泊松回归,普通最小二乘,加权负二项式模型
- R语言中回归和分类模型选择的性能指标
- R语言 线性混合效应模型实战案例
- R语言中敏感性和特异性、召回率和精确度作为选型标准的华夫图案例
- R语言中的多类别问题的绩效衡量:F1-score 和广义AUC
- Dart语言基础Map、List、Set操作合辑
- 2.2.2 类反射场景与使用 -《SSM深入解析与项目实战》
- 每天手撕一道算法-64. 最小路径和
- Flutter 1.20 下的 Hybrid Composition 深度解析
- Flutter 1.17 对列表图片的优化解析
- SQL注入常用函数和关键字总结
- 用遗传算法求解函数
- javafx框架tornadofx实战-益智游戏-找出指定的内容1
- Qt音视频开发8-ffmpeg保存裸流
- PyTorch6:nn.Linear&常用激活函数