Spring学习记录3——Spring AOP
SpringAOP基础
AOP简介:
AOP是Aspect Oriented Programing的简称,翻译为“面向切面编程”。它适用于具有横切逻辑的应用场合,如性能检测,访问控制,事务管理及日志记录。
在开发中,在业务层有时会涉及到事务的处理和性能检测,例如粗体是事务有关的代码,这些代码和业务逻辑混合在了同一个方法中。

很多时候这些代码和业务逻辑没法分离,并且这些代码是重复代码,AOP通过横向抽取机制为这类代码提供解决方案。AOP将这些分散在各个业务逻辑的代码中的相同代码通过横向切割的方式抽取到一个独立模块中,让业务逻辑类不会和其他内容混合在一起。

AOP术语:
1、连接点(JoinPoint)
特定点是程序执行的某个特定位置,如类初始化前、类初始化后、类的某个方法调用前/后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些点被称为“连接点”。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时及方法调用前后这些程序执行点织入增强。
连接点由两个信息确定:一是方法表示的程序执行点;二是用相对位置表示的方位。如对于在run()方法执行前的连接点,执行点位run(),方位为该方法执行前。Spring使用切点对执行点进行定位,而方位则在增强类型中定义。
2、切点(Pointcut)
每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点。在众多连接点中,如何定位某些连接点呢?AOP通过“切点”定位特定的连接点。书上原文:借助数据库查询的概念来理解切点和连接点的关系再适合不过了;连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。 可理解为类中的某个方法。
连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,如果希望定位到具体的特殊点上(如方法执行前、执行后),还需要提供方位信息。
3、增强(Advice)
增强是织入目标类连接点上的一段程序代码。在Spring中,增强除用于描述一段程序代码外,还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点的方位信息和切点信息,就可以找到特定的连接。
正是由于增强既包含用于添加到目标连接点上的一段执行逻辑,又包含用于定位连接点的方位信息,所以Spring提供的增强接口都是带方位名的,如BeforeAdvice、AfterReturningAdvice等。所以只有结合切点和增强,才能确定特定的连接点并实施增强逻辑。
4、目标对象(Target)
增强逻辑的织入目标类。如果没有AOP,目标类需要自己实现所有逻辑,例如事务开启->业务逻辑->提交事务。在AOP的帮助下,目标类秩序实现那些非横切逻辑的程序逻辑(业务逻辑),而事务管理、性能监视等横切逻辑可以通过AOP动态织入到特定的连接点上。
5、引介(Introduction)
引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,也可以动态地为该业务添加接口的实现逻辑,让业务类成为这个接口的实现类。
6、织入(Weaving)
织入是将增强添加到目标类的具体链接点上的过程。根据不同的实现技术,AOP有3种织入方式:
(1)编译期织入,这要求使用特殊的Java编译器。
(2)类装载期织入、这要求使用特殊的类装载器。
(3)动态代理织入、在运行期为目标类添加增强生成子类的方式。
Spring采用动态代理织入、而AspectJ采用编译期织入和类装载期织入。
7、代理(Proxy)
一个类被AOP织入增强后,就产生了一个结果类,该类结合了原类和增强逻辑的代理类。
8、切面(Aspect)
切面由切点和增强组成,它即包括横切逻辑的定义(需要织入的逻辑),也包括连接点的定义(织入位置的定位)。Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入切面所指定的连接点中。
AOP工具的设计目标是把横切的问题(如性能监视、事务管理)模块化。位于AOP工具核心的是连接点模型,它提供了一种机制,可以定位到需要在哪里发生横切。
Spring AOP使用的代理机制:
Spring AOP使用了两种代理机制:一种是基于JDK的动态代理,一种是基于CGLib的动态代理。之所以需要两种代理机制,很大程度是因为JDK本身只提供接口的代理,而不支持类的代理。
AOP所做的内容通过动态代理技术也可以实现,Spring AOP的底层也是通过这种技术实现的。然而,通过动态代理实现有几个需要改进的地方:
1、目标类的所有方法都添加了横切逻辑,我们可能只希望对特定方法添加横切逻辑。
2、通过硬编码的方式制定了织入横切逻辑的织入点,即在目标类业务方法的开始和结束前织入代码。
3、手工编写代理实例的创建过程,在为不同类创建代理时,需要分别编写相应的创建代码,无法做到通用。
以上3个问题在AOP中占有重要的地位,因为Spring AOP的主要工作就是围绕以上3点展开的:Spring AOP通过Pointcut(切点)指定在哪些类的哪些方法织入横切逻辑,通过Advice(增强)描述横切逻辑和方法的具体织入点(方法前、方法后、方法两端等)。此外,Spring通过Advisor(切面)将Pointcut和Advice组装起来。有了Advisor的信息,Spring就可以利用JDK和CGLib动态代理技术采用统一的方式为目标Bean创建织入的代理对象了。
CGLib和JDK动态代理的选择:
CGLib所创建的动态代理对象的性能比JDK所创建的动态代理对象的性能提高不少。但是CGLib在创建代理对象时所花费的时间却比JDK动态代理多。对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建代理对象,所以比较适合采用CGLib动态代理技术,反之则适合采用JDK动态代理技术。
定义切面
Spring定义切面的方式有4种,他们的本质都是相同的,都是定义切点和增强,只是在表示形式上有所不同。

小结:
AOP是OOP的延伸,它为程序开发提供了一个崭新的思考角度,可以将重复性的横切逻辑抽取到统一的模块中通过OOP的纵向抽象和AOP的横向抽取,程序才可以真正解决重复性代码问题。
Spring学习记录3——Spring AOP的更多相关文章
- Spring学习记录(十二)---AOP理解和基于注解配置
Spring核心之二:AOP(Aspect Oriented Programming) --- 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软 ...
- Spring学习记录4——Spring对DAO的支持
Spring对DAO的支持 随着持久化技术的持续发展,Spring对多个持久化技术提供了集成支持,包括Hibernate.MyBatis.JPA.JDO:此外,还提供了一个简化JDBC API操作的S ...
- 我的Spring学习记录(二)
本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...
- 我的Spring学习记录(四)
虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...
- 我的Spring学习记录(五)
在我的Spring学习记录(四)中使用了注解的方式对前面三篇做了总结.而这次,使用了用户登录及注册来对于本人前面四篇做一个应用案例,希望通过这个来对于我们的Spring的使用有一定的了解. 1. 程序 ...
- Spring 学习记录8 初识XmlWebApplicationContext(2)
主题 接上文Spring 学习记录7 初识XmlWebApplicationContext refresh方法 refresh方法是定义在父类AbstractApplicationContext中的. ...
- Spring 学习记录3 ConversionService
ConversionService与Environment的关系 通过之前的学习(Spring 学习记录2 Environment),我已经Environment主要是负责解析properties和p ...
- Spring 学习记录6 BeanFactory(2)
主题 除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类. 结构 DefaultListabl ...
- Spring学习1:Spring基本特性
http://longliqiang88.github.io/2015/08/14/Spring%E5%AD%A6%E4%B9%A01%EF%BC%9ASpring%E5%9F%BA%E6%9C%AC ...
随机推荐
- Python--day43--mysql自增列之起始值和步长
对于自增: 1,查看字段,类型以及是否可以为空,默认值:desc t2; 2,查看表t2是怎么创建的show create table t2; (竖着看)查看表t2是怎么创建的show create ...
- P1021 整数奇偶排序
整数奇偶排序 题目出处:<信息学奥赛一本通>第二章上机练习6,略有改编 题目描述 告诉你包含 \(n\) 个数的数组 \(a\) ,你需要把他们按照"奇数排前面,偶数排后面:奇数 ...
- egg-socket在egg中的使用
WebSocket 的产生源于 Web 开发中日益增长的实时通信需求,对比基于 http 的轮询方式,它大大节省了网络带宽,同时也降低了服务器的性能消耗: socket.io 支持 websocket ...
- Linux 内核存取配置空间
在驱动已探测到设备后, 它常常需要读或写 3 个地址空间: 内存, 端口, 和配置. 特别 地, 存取配置空间对驱动是至关重要的, 因为这是唯一的找到设备被映射到内存和 I/O 空间的位置的方法. 因 ...
- python tkinter动态追加按钮等控件可能遇到的问题
小爬最近给同事制作一个小爬虫:具体要求: 1.每天自动定时触发: 2.模拟用户自动登陆: 3.自动爬取对应API接口数据: 4.对爬取结果进行逻辑判断,对符合条件的数据进行规则化列示: 5.列示的行项 ...
- DOCKER学习_008:Docker容器的运行最佳实践
一 容器分类 容器按用途大致可分为两类: 服务类容器,如 web server. database等 工具类容器,如cur容器, Iredis-cli容器 通常而言,服务类容器需要长期运行,所以使用 ...
- centos批量创建用户并发送邮件,(修订版)
# cat user_create.sh echo -n "创建用户输入C,删除用户输入D!" read name function monitor() { if [ " ...
- (Go) 1. go环境配置
第一步: 下载配置环境 转载: https://www.liwenzhou.com/posts/Go/go_menu/ 1.下载地址: https://golang.google.cn/dl/ 2.安 ...
- Java高级特性——注解(Annotation)
文件地址:https://github.com/xiaozhengyu/StudyNotes.git
- linux Nginx-1.10.2 安装部署教程
一.下载Nginx以及依赖组件[root@localhost src]# wget http://nginx.org/download/nginx-1.10.2.tar.gz [root@localh ...