4.1AOP所要解决的问题
将横切关注点(包裹在业务代码外层)与业务逻辑相分离,AOP实现将横切关注点与他们所影响的对象之间的解耦。除此之外,AOP还还会在声明式事务、安全和缓存进行应用。
AOP用于重用通用功能,传统方式最常见的是继承和委托。继承会造成对象体系非常脆弱,委托会对委托对象进行复杂的对象,AOP提供了另一种可选方案。我们通过声明式的方式定义这个功能要以何种方式在何处应用,而无需求改受影响的类。横切关注点可以被模块化为特殊的类,这些类被称为切面(aspect)。
优点:
- 1.每个关注点都集中于一个地方,而不是分散到代码中
- 2.服务模块更简洁,只包含核心代码,关注点的代码都被转移到切面中
4.2 相关术语
- 通知(advice)
- 切点(pointcut)
- 连接点(joinpoint)
4.2.1 通知
切面的工作被称为通知。
- 前置通知(Before):在目标方法被调用之前调用通知功能
- 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么
- 返回通知(After-returning):在目标方法成功执行之后调用通知
- 异常通知(After-throwing):在目标方法抛出异常后调用通知
- 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
4.2.2 连接点
连接点是可以插入切面的一个点(时间点)。例如方法执行前、方法执行后、抛出异常时…等等。
4.2.3 切点
定义切面在何处(位置点)进行通知。
4.2.4 切面
切面是通知和切点的结合。
4.2.5 引入
引入允许我们向现有的类添加新的方法或属性。
4.2.6 织入
织入是把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。
在目标对象的生命周期里有多个点可以进行织入:
- 编译期:切面在目标类编译时被织入。例如AspectJ的织入编译器。
- 类加载期:切面在目标被加载到JVM时被织入。例如AspectJ5.
- 运行期:切面在应用运行的某个时刻被织入。一般情况啊下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面的。(学习下反射和动态代理哦)
4.3 切点表达式语言
知道AspectJ是一种切点表达式语言就够啦。用起来超级简单。
以下注释部分是配置是说明如何通过AspectJ表达式来匹配该方法作为切点。
创建一个表演类,我们要在表演前后做一些动作
|
|
创建观众类作为切面
|
|
基于类的Spring配置
|
|
测试方法
|
|
输出
观众们请关闭手机铃声...
大家请坐...
我表演啦
大家请鼓掌...
使用XML配置
|
|
测试
|
|
环绕通知
修改切面类
|
|
其他不变,测试结果环绕-手机静音
环绕-就坐
我表演啦
环绕-牛b牛b!再来一个!
带参数的通知
我们通过编写切面来统计CD磁盘中的某个歌曲被播放了几次
播放器类
|
|
切面类
|
|
配置类
|
|
测试
|
|
输出
|
|
4.4 在XML中声明切面
当你需要声明切面,但又不能为通知类添加注解的时候,那么就必须转向XML配置了。
AOP配置元素 | 用途 |
---|---|
定义AOP通知器 | |
定义AOP后置通知(不管被通知的方法是否执行成功) | |
定义AOP返回通知 | |
定义AOP异常通知 | |
定义AOP环绕通知 | |
定义一个切面 | |
启动@AspectJ注解驱动的切面 | |
定义一个AOP前置通知 | |
顶层的AOP配置元素。大多数的 |
|
以透明的方式呗通知的对象引入额外的接口 | |
定义一个切点 |
将切面的注解去掉
|
|
配置xml
|
|
注意 修改以下Main测试类的配置读取方式,将Java配置类改为配置文件配置。
|
|
5 小结
本章讲解了通过切面类和配置文件配置实现Spring的AOP功能,使模块之间进行解耦,有效减少了代码冗余,让我们只关注类自身的功能。
通过这几章我们学习了Spring和核心功能,DI和AOP。但是我们现在只停留在了会用的阶段,要深入其原理还需要看看源码,下一章开始学习SpringMVC。开始构建真正的Web应用。