aop注解配置切点 spring_Spring AOP 之 通知、连接点、切点、切面。

1:知识背景

软件系统可以看成是由一组关注点组成的,其中,直接的业务关注点,是直切关注点。而为直切关注点提供服务的,就是横切关注点。

2:面向切面的基本原理

什么是面向切面编程

横切关注点:影响应用多处的功能(安全、事务、日志)

切面:

横切关注点被模块化为特殊的类,这些类称为切面

优点:

每个关注点现在都集中于一处,而不是分散到多处代码中

服务模块更简洁,服务模块只需关注核心代码。

AOP 术语

通知:

定义:切面也需要完成工作。在 AOP 术语中,切面的工作被称为通知。

工作内容:通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决何时执行这个工作。

Spring 切面可应用的 5 种通知类型:

Before——在方法调用之前调用通知

After——在方法完成之后调用通知,无论方法执行成功与否

After-returning——在方法执行成功之后调用通知

After-throwing——在方法抛出异常后进行通知

Around——通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为

连接点:

定义:连接点是一个应用执行过程中能够插入一个切面的点。

连接点可以是调用方法时、抛出异常时、甚至修改字段时、

切面代码可以利用这些点插入到应用的正规流程中

程序执行过程中能够应用通知的所有点。

切点:

定义:如果通知定义了“什么”和“何时”。那么切点就定义了“何处”。切点会匹配通知所要织入的一个或者多个连接点。

通常使用明确的类或者方法来指定这些切点。

作用:定义通知被应用的位置(在哪些连接点)

切面:

定义:切面是通知和切点的集合,通知和切点共同定义了切面的全部功能——它是什么,在何时何处完成其功能。

引入:

引入允许我们向现有的类中添加方法或属性

织入:

织入是将切面应用到目标对象来创建的代理对象过程。

切面在指定的连接点被织入到目标对象中,在目标对象的生命周期中有多个点可以织入

编译期——切面在目标类编译时期被织入,这种方式需要特殊编译器。AspectJ的织入编译器就是以这种方式织入切面。

类加载期——切面在类加载到

JVM ,这种方式需要特殊的类加载器,他可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5 的 LTW 就支持这种织入方式

运行期——切面在应用运行期间的某个时刻被织入。一般情况下,在织入切面时候,AOP 容器会为目标对象动态的创建代理对象。Spring AOP 就是以这种方式织入切面。

3:Spring 对 AOP 的支持

并不是所有的 AOP 框架都是一样的,他们在连接点模型上可能有强弱之分。

有些允许对字段修饰符级别应用通知

有些支持方法调用连接点

Spring 提供的 4 种各具特色的 AOP 支持

基于代理的经典 AOP;

@AspectJ 注解驱动的切面;

纯 POJO 切面;

注入式 AspectJ 切面; Spring

在运行期间通知对象

通过在代理类中织入包裹切面,Spring 在运行期间将切面织入到 Spring 管理的 Bean 中。

代理类封装了目标类,并拦截被通知的方法调用,再将调用转发给真正的目标 Bean

当拦截到方法调用时,在调用目标 Bean 方法之前,代理会执行切面逻辑。

当真正应用需要被代理的 Bean 时,Spring 才创建代理对象。如果使用 ApplicationContext,在 ApplicationContext 从 BeanFactory 中加载所有 Bean 时,Spring 创建代理对象,因为 Spring 在运行时候创建代理对象,所以我们不需要特殊的编译器来织入 Spring AOP 的切面。

Spring 支持方法创建连接点

因为 Spring 基于动态代理,所以 Spring 只支持方法连接点。

Spring 缺失对字段连接点的支持,无法让我们更加细粒度的通知,例如拦截对象字段的修改

Spring 缺失对构造器连接点支持,我发在 Bean 创建时候进行通知。

4:使用切点选择连接点

切点用于准确定位,确定在什么地方应用切面通知。

Spring 定义切点

在 Spring AOP 中,需要使用 AspectJ 的切点表达式来定义切点。

AspectJ 指示器

描述

arg ()

限制连接点的指定参数为指定类型的执行方法

@args ()

限制连接点匹配参数由指定注解标注的执行方法

execution ()

用于匹配连接点的执行方法

this ()

限制连接点匹配 AOP 代理的 Bean 引用为指定类型的类

target ()

限制连接点匹配特定的执行对象,这些对象对应的类要具备指定类型注解

within()

限制连接点匹配指定类型

@within()

限制连接点匹配指定注释所标注的类型(当使用 Spring AOP 时,方法定义在由指定的注解所标注的类里)

@annotation

限制匹配带有指定注释的连接点

1. 创建自己的切点

- execution( ) 指示器选择 Instrument 的 play( ) 方法。

方法表达式是以 * 号开头,标识了我们不关心的方法返回值的类型。

* 后我们指定了权限定类名和方法名。

对于方法的参数列表,使用(..)标识切点选择任意的 play( ) 方法,无论入参是什么。

- 假设我们需要匹配切点仅匹配 com.Springinaction.springidol 包。可以使用 within()

注意 && 是将 execution( ) 和 within( ) 连接起来,形成的 and 关系。同理也可以使用 || 或关系、!非关系

- 创建 Spring 的 bean( ) 指示器

Spring 2.5 引入一个新的 bean( ) 指示器,该指示器允许我们在切点表达式中使用 Bean ID 来标识 Bean

bean( ) 使用 Bean ID 或 Bean 名称作为参数来限制切点只匹配特定 Bean。

如下,我们希望执行 Instrument 的 play( ) 方法时候应用通知,但限定 Bean 的 ID 为 eddie

还可以使用非操作作为除了指定 ID 的 Bean 以外的其他 Bean应用通知

在此场景下,切面会通知被编织到所有 ID 不为 eddie 的 Bean 中

5:在 XML 中声明切面

Spring 的 AOP 配置元素简化了基于 POJO 切面声明

AOP 配置元素

描述

aop : advisor

定义 AOP 通知器

aop : after

定义 AOP 后置通知(不管被通知方法是否执行成功)

aop : after-returing

定义 AOP after-returing 通知

aop : after-throwing

定义 AOP after-throwing 通知

aop : around

定义 AOP 环绕通知

aop : aspect

定义切面

aop : aspectj-autoproxy

启动 @AspectJ 注解驱动的切面

aop : before

定义 AOP 前置通知

aop : config

顶层的 AOP 配置元素,大多数 aop : * 元素必须包含在 元素内

aop : declare-parents

为被通知的对象引入额外接口,并透明的实现

aop : pointcut

定义切点

时间: 05-06

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值