学习Spring5必知必会(5)~Spring AOP
一、学习 AOP 思想的准备工作:
1、横切面关注点
在开发中,为了给业务方法中增加日志记录,权限检查,事务控制等功能,此时我们需要在修改业务方法内添加这些零散的功能代码(横切面关注点)。
这些零散存在于业务方法中的功能代码【例如:日志记录,权限检查,事务控制】,我们称之为
横切面关注点
,横切面关注点不属于业务范围,应该 从业务代码中剥离出来.
2、AOP思想 (Aspect Oritention Programming):面向切面编程的思想
切面:
把一个个的横切关注点放到某个模块中去
,称之为切面。那么每一个的切面都能影响业务的某一种功能,
切面的目的就是功能增强
,如日志切面就是一个横切关注点,应用中许多方法需要做日志记录的只需要插入日志的切面即可.
3、AOP 思想的原理:是动态代理
4、了解 AOP 术语:
Joinpoint
:连接点,被拦截到需要被增强的方法
。
where:去哪里做增强
- Pointcut:切入点,哪些包中的哪些类中的哪些方法,可认为是连接点的集合。
where:去哪些地方做增强
Advice
:增强(通知),当拦截到 Joinpoint 之后,在方法执行的什么时机(when)做什么样(what)的增强
。 根据时机分为:前置增强、后置增强、异常增强、最终增强、环绕增强
Aspect
:切面,Pointcut+Advice, 去哪些地方+在什么时机+做什么增强
Target:目标对象,被代理的目标对象,委托对象。
Weaving:织入,把 Advice 加到 Target 上之后,创建出 Proxy 对象的过程。
Proxy:一个类被 AOP 织入增强后,产生的代理类 Advice(增强)执行时机,代理对象。
5、Pointcot 语法 【找到具体的某个方法-哪个包.哪个类.哪个方法
】
(1)AspectJ 切入点语法如下(表示在哪些包下的哪些类中的哪些方法上做切入增强):
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
即 ★execution(<修饰符>? <返回类型> <声明类型>? <方法名>(<参数>) <异常>)
- 例子:public static Class java.lang.Class.forName(String className)throws ClassNotFoundException
(2)切入点表达式中的通配符(看具体的方法,先从方法名位置开始看
):
*:匹配任何部分,但是只能表示一个单词。
..:可用于全限定名中和方法参数中,分别表示子包和 0 到 N 个参数。
二、AOP 开发:
1、依赖:
- spring-aop.jar
- com.springsource.org.aopalliance.jar [spring5的spring-aop.jar已经包含]
- com.springsource.org.aspectj.weaver.jar
2、配置:
(1)引入AOP的约束(在beans的基础进行修改即可)
- 当然也可以使用插件sts,打开xml文件方式选择 Spring Config Editor
(2)配置AOP:
<!-- AOP 配置:在什么地点、什么时机、做什么 -->
<!-- 1、what【what(人物)】:做什么增强(关联what) -->
<bean id="transactionManager" class="com.shan.tx.TransactionManager"/>
<aop:config proxy-target-class="false"> <!-- 属性proxy-target-class配置是否使用真实对象 -->
<!-- 配置AOP切面 -->
<aop:aspect ref="transactionManager"> <!-- 关联what -->
<!-- 2、where【where+what(地点+人物)】:在哪些包中的哪些类中的哪些方法上做增强 -->
<aop:pointcut id="txPoint" expression="execution(* com.shan.service..*Service*.*(..))"/>
<!-- 3、when【when+where+what(时间+地点+人物)】:在方法执行的什么时机(在哪里where-关联pointcut)做增强 -->
<aop:before method="open" pointcut-ref="txPoint"/>
<aop:after-returning method="commit" pointcut-ref="txPoint"/>
<aop:after-throwing method="rollback" pointcut-ref="txPoint"/>
<aop:after method="close" pointcut-ref="txPoint"/>
<aop:around method="aroundMethod" pointcut-ref="txPoint"/>
</aop:aspect>
</aop:config>
三、AOP 各种增强
1、增强的分类:
■ 根据被增强的方法
的执行时机分为:前置增强、后置增强、异常增强、最终增强、环绕增强
- 前置增强:权限控制、日志记录等 [被增强的方法执行之前]
- 后置增强:提交事务、统计分析数据结果等 [被增强的方法正常执行之后(中途没有异常)]
- 最终增强:回滚事务、记录日志异常信息等 [被增强的方法出现异常]
- 最终增强:释放资源等 [finally最后操作]
- 环绕增强:缓存、性能日志、权限、事务管理等 [可以自定义在被增强方法的什么时机执行(返回一个Object,参数processdingJoinpoint)]
2、增强细节:
(1)获取异常的信息:
public void rollback(Throwable ex) {
System.out.println("回滚事务~,异常信息:" +ex.getMessage());
}
(2)获取被增强方法的信息【获取被增强方法的信息,并且可以传递给增强方法】:
- Spring AOP:Joinpoint类 连接点,访问被增强方法的真实对象,代理对象,方法参数等
- 可以作为前置、后置、异常、最终增强方法的参数,
第一个参数
//可以作为前置、后置、异常、最终增强方法的参数,**`第一个参数`**
public void open(JoinPoint jp) {
System.out.println("开启事务~");
System.out.println("代理对象:" +jp.getThis().getClass());
System.out.println("目标对象:" +jp.getTarget().getClass());
System.out.println("被增强方法的参数:" +Arrays.toString(jp.getArgs()));
System.out.println("连接点方法的签名:" +jp.getSignature());
System.out.println("当前连接点的类型:" +jp.getKind());
}
(3) 环绕增强方法调用真实对象的方法【参数processdingJoinpoint】:
参数processdingJoinpoint:是JointPoin 的子类,只能用于环绕增强,
作为第一个参数
还可以调用真实对象中被增强的方法。
//调用真实对象的方法 ret = pjp.proceed();
public Object aroundMethod(ProceedingJoinPoint pjp) {
Object ret = null;
System.out.println("开启事务~");
try {
ret = pjp.proceed();//调用真实对象的方法
System.out.println("调用真实对象的方法...~");
System.out.println("提交事务~");
} catch (Throwable e) {
System.out.println("回滚事务~,错误信息:" + e.getMessage());
}finally {
System.out.println("关闭资源~");
}
return ret;
}
四、使用注解配置AOP
AOP 注解:
(1)在配置文件中添加注解的解析器的配置【第三方程序(赋予注解的特殊功能)】:
- 使用cglib注解:配置属性proxy-target-class="true"
<!-- AOP注解的解析器 -->
<aop:aspectj-autoproxy/>
(2)使用注解@Aspect
(配置一个AOP切面
)
- @Pointcut (
配置where
) - @Before、@AfterReturning、@AfterThrowing、@After、@Around(
配置when
)
@Component@Aspect //配置一个AOP切面
public class TransactionManager {
//where
//xml:<aop:pointcut id="txPoint" expression="execution(* com.shan.service..*Service*.*(..))"/>
@Pointcut("execution(* com.shan.service..*Service*.*(..))")
public void txPoint() {
}
//@Before("txPoint()")
public void open(JoinPoint jp) {
System.out.println("开启事务~");
}
//@AfterReturning("txPoint()")
public void commit() {
System.out.println("提交事务~");
}
//@AfterThrowing(value="txPoint()", throwing="ex")
public void rollback(Throwable ex) {
System.out.println("回滚事务~,异常信息:" +ex.getMessage());
}
//@After("txPoint()")
public void close() {
System.out.println("关闭资源~");
}
@Around("txPoint()")
public Object aroundMethod(ProceedingJoinPoint pjp) {
Object ret = null;
System.out.println("开启事务~");
try {
ret = pjp.proceed();//调用真实对象的方法
System.out.println("调用真实对象的方法...~");
System.out.println("提交事务~");
} catch (Throwable e) {
System.out.println("回滚事务~,错误信息:" + e.getMessage());
}finally {
System.out.println("关闭资源~");
}
return ret;
}
}
学习Spring5必知必会(5)~Spring AOP的更多相关文章
- [ 学习路线 ] 2015 前端(JS)工程师必知必会 (2)
http://segmentfault.com/a/1190000002678515?utm_source=Weibo&utm_medium=shareLink&utm_campaig ...
- 《SQL必知必会》学习笔记二)
<SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...
- 学习《SQL必知必会(第4版)》中文PDF+英文PDF+代码++福达BenForta(作者)
不管是数据分析还是Web程序开发,都会接触到数据库,SQL语法简洁,使用方式灵活,功能强大,已经成为当今程序员不可或缺的技能. 推荐学习<SQL必知必会(第4版)>,内容丰富,文字简洁明快 ...
- 《MySQL必知必会》学习笔记——前言
前言 MySQL已经成为世界上最受欢迎的数据库管理系统之一.无论是用在小型开发项目上,还是用来构建那些声名显赫的网站,MySQL都证明了自己是个稳定.可靠.快速.可信的系统,足以胜任任何数据存储业务的 ...
- 《SQL必知必会》学习笔记整理
简介 本笔记目前已包含 <SQL必知必会>中的所有章节. 我在整理笔记时所考虑的是:在笔记记完后,当我需要查找某个知识点时,不需要到书中去找,只需查看笔记即可找到相关知识点.因此在整理笔记 ...
- 《SQL必知必会》学习笔记(一)
这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...
- mysql学习--mysql必知必会1
例如以下为mysql必知必会第九章開始: 正則表達式用于匹配特殊的字符集合.mysql通过where子句对正則表達式提供初步的支持. keywordregexp用来表示后面跟的东西作为正則表達式 ...
- mysql学习--mysql必知必会
上图为数据库操作分类: 下面的操作參考(mysql必知必会) 创建数据库 运行脚本建表: mysql> create database mytest; Query OK, 1 row ...
- 数据库学习之中的一个: 在 Oracle sql developer上执行SQL必知必会脚本
1 首先在開始菜单中打开sql developer: 2. 创建数据库连接 点击左上角的加号 在弹出的对话框中填写username和password 測试假设成功则点击连接,记得角色要写SYSDBA ...
- SQL必知必会,带你系统学习
你一定听说过大名鼎鼎的Oracle.MySQL.MongoDB等,这些数据库都是基于一个语言标准发展起来的,那就是SQL. SQL可以帮我们在日常工作中处理各种数据,如果你是程序员.产品经理或者是运营 ...
随机推荐
- Win7升级Win11升级记录及教程 【错误码(0×8004242d)】
hellow,大家好,我是公众号棱镜Prism K的[K君].家中电脑因为一些原因不得不进行升级,下面是我对这次电脑升级所进行的记录. step 1.打开微软官网,找到对应的WIN11下载模块,这里注 ...
- wordcount报错:org.apache.hadoop.mapreduce.lib.input.InvalidInputException: Input path does not exist:
Exception in thread "main" org.apache.hadoop.mapreduce.lib.input.InvalidInputException: In ...
- golang中接口对象的转型
接口对象的转型有两种方式: 1. 方式一:instance,ok:=接口对象.(实际类型) 如果该接口对象是对应的实际类型,那么instance就是转型之后对象,ok的值为true 配合if...el ...
- Nginx代理常用参数
目录 一:Nginx代理常用参数 1.添加发往后端服务器的请求头信息 二:参数案例 1.lb01配置文件 2.web01 web02 web服务器 3.测试 4.重启 5.DNS域名解析 6.网址测试 ...
- ORA-15081: failed to submit an I/O operation to a disk
Problem: While restoring controlfile to test environment, from filesystem or tape environment after ...
- Redis 学习笔记(一)redis 数据类型和对象机制
Redis 简介 Redis 是(key-value)的 NoSQL 数据库,所有的 key 都是 String ,它的 value 可以是 String.hash.list.set.zset(有序集 ...
- Java 锁 概念介绍
一 Java中的锁是什么? /* * 一 Java锁定义? * 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制. * 锁旨在强制 ...
- 洛谷P2240 【深基12.例1】部分背包问题(经典模板)
首先应该注意几个关键信息:装走尽多的金币.所有金币可以随意分割并且分割后金币的价值比不变; 我们可以抽象成一个买东西的场景,给你一定数目的钱,让你在这些钱内尽量在超市买更多的小零食,这就牵扯到了一个性 ...
- react-(错误代码#31----Minified React error #31)
错误描述:Uncaught Invariant Violation: Minified React error #31; visit http://facebook.github.io/react/d ...
- C语言system函数
我们今天来看看在windows操作系统下system () 函数详解(主要是在C语言中的应用) 注意:在windows下的system函数中命令可以不区别大小写! 函数名: system 功 能: 发 ...