该篇博客就开始Spring的AOP之旅了,本篇博客主要阐述一些AOP的理解性问题
该篇博客主要阐述
1、面向切面编程(AOP)主要用来解决哪一些问题
2、什么是面向切面编程(AOP)
3、AOP相关术语
4、Spring对AOP的支持
一、面向切面编程(AOP)主要用来解决哪一些问题
在开发中,分布于应用中多处的功能被称为横切关注点(cross-cutting concerns).通常这些横切关注点从概念上是与应用的核心业务逻辑相分离的。将这些横切关注点与核心业务逻辑相分离,这就是面向切面编程(AOP)所要解决的问题
依赖注入有助于应用对象之间的解耦,而AOP可以实现横切关注点与它们所影响的对象之间的解耦
常用场景
- 日志
- 声明式事务
- 安全
- 缓存
二、什么是面向切面编程(AOP)
通过上面的阐述,大概了解了面向切面解决哪些问题,到底什么是面向切面,将在此条做出解释
如图三个切面(安全、日志、事务)影响这四个核心业务
横切关注点可以被描述为影响应用多处的功能,比如你需要在许多方法执行完毕后打一个log,我们可以在这些方法执行完毕后的语句中添加log,但是加入方法很多,会很麻烦,而且让业务逻辑相当的不清晰。所以AOP就是来完成这个不必要的麻烦。在使用面向切面编程时,我们仍然在一个地方定义通用的功能,我们可以通过声明式的方式来定义这些功能以何种方式在何处应用,而无需修改受影响的类。这些横切关注点可以被模块化为一个特殊的类,这些类被称为切面
好处
- 每个横切关注点都集中于一处,而不是分散到多处代码中
- 核心业务模块更加简介,因为它们只包含核心代码,而不会有log等次要业务
三、AOP相关术语
切面
横切关注点可以被模块化为特殊的类,这些类被称为切面
通知(Advice)
在AOP术语中,切面的工作被称为通知。通知定义了切面是什么以及何时使用(比如这个工作应该应用于某个方法之前或之后等等)
Spring切面可以应用5中类型的通知
- Before:在方法被调用之前调用通知
- After:在方法完成之后被调用通知,无论方法执行是否成功
- AfterReturning:在方法成功执行之后调用通知
- AfterThrowing:在方法抛出异常后调用通知
- Around:通知包裹了被通知的方法,在被通知方法调用之前和调用之后执行自定义的行为
连接点(Joinpoint)
在系统运行之前,AOP的功能模块需要织入到OOP的功能模块中。所以,要进行这种织入过程我们需要知道在系统的哪些执行点上进行织入操作,这些将要在其之上进行织入操作的系统执行点就称为Joinpoint。这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程中,并添加新的行为
切点(Poincut)
如果通知定义了切面的“什么”和“何时”,那么切点就定义了“何处”
Poincut的表述方式
- 直接指定JoinPoint所在的方法名称
- 正则表达式
有些AOP框架允许我们创建动态的切点,可以根据运行时的决策(比如方法的参数值)来决定是否应用通知
引入(Introduction)
引入允许我们向现有的类添加新方法或者属性,可以实现无需修改这些现有的类的情况下,让它们具有新的行为和状态
织入(weaving)
织入是将切面应用到目标对象来创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在目标对象的生命周期里有多个点可以进行织入
- 编译期——切面在目标类编译时被织入。AspectJ就是以这种方式织入切面的
- 类加载期——切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的LTW(load-time weaving)就支持以这种方式织入切面
- 运行期——切面在应用运行的某个时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象。Spring AOP就是以这种方式织入切面的
四、Spring对AOP的支持
并不是所有AOP框架都是一样的,现在AOP框架有三个是最常见的
- AspectJ
- JBoss AOP
- Spring AOP
Spring AOP只支持ioc容器管理的Bean,其他的普通java类无法支持aop。同时Spring整合了aspectj,使得Spring体系中可以使用aspectj语法来实现aop
Spring AOP与AspectJ的区别
AspectJ
AspectJ是一个面向切面的框架,它扩展了Java语言,AspectJ定义了AOP语法,所以它有一个专门的编译器用来遵守Java字节编码规范的Class文件
Spring AOP
Spring提供了四种类型的AOP支持
- 基于代理的经典Spring AOP
- @AspectJ注解驱动的切面
- 纯POJO切面
- 注入式AspectJ切面(适合Spring各版本)
Spring AOP与AspectJ联系(Spring AOP借鉴了Aspect的模型)
实际上POJO只是提供了满足切点条件时所需调用的方法,但是这种技术需要XML进行配置,而不能支持注解。所以Spring借鉴了AspectJ的切面,所以提供了@AspectJ注解驱动的切面,本质上依然是Spring基于代理的AOP,只是编程模式以及方法与AspectJ类似了,不需要XML配置
参考
《Spring IN ACTION》
《Spring 揭秘》