Spring实战笔记——面向切面编程(一)

上一章基本完成了Spring依赖注入的相关学习,本章进入面向切面编程的学习。本文先对面向切面编程的思想进行记录,下一阶段进行深入的学习。

本章内容

  1. 面向切面编程的基本原理
  2. 通过POJO创建切面
  3. 使用@AspectJ注解
  4. 为AspectJ切面注入依赖

引言——在软件开发中,散布于应用中多处的功能被称为横切关注点(cross-cutting concern),横切关注点应该是与业务逻辑相分离的,实现这种分离就是面向切面编程(AOP)要解决的问题。

1,什么是AOP

切面的常用术语有通知(advice)、切点(pointcut)和连接点(joint point)。如图所示:
这里写图片描述

1.1 通知

切面的工作被称为通知。通知定义了切面是什么以及何时使用。Spring切面可以应用5种类型的通知:

  1. 前置通知(Before):在目标方法被调用之前调用通知功能;
  2. 后置通知(After):在目标方法完成之后调用再通知,此时不关心方法的输出是什么;
  3. 返回通知(After-returning):在目标方法成功执行之后调用通知;
  4. 异常通知(After-throwing):在目标方法抛出异常后调用通知;
  5. 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。

1.2 连接点

连接点是在应用执行过程中能够插入切面的一个点,这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。

1.3 切点

一个切面并不需要通知应用的所有连接点。切点有助于缩小切面所通知的连接点的范围。
如果说通知定义了切面的“什么”和“何时”的话,那么切点就定义了何处

1.4 切面

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

1.5 引入

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

1.6 织入

织入是把切面应用到目标对象并创建新的代理对象的过程。在目标对象的生命周期里有多个点可以进行织入:

  1. 编译器:切面在目标类编译时被织入。这种方式需要特殊的编译器
  2. 类加载期:切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码。
  3. 运行期:切面在应用运行的某个时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。

Spring提供了4中类型的AOP支持:

  1. 基于代理的经典Spring AOP;
  2. 纯POJO切面;
  3. @AspectJ注解驱动的切面;
  4. 注入式AspectJ切面(适用于Spring各版本)。

Spring AOP构建在动态代理基础之上,因此,Spring对AOP的支持局限于方法拦截。

在基于XML的配置中,可以使用Spring的aop命名空间将纯POJO转换为切面,这些POJO只是提供了满足切点条件时所要调用的方法。

Spring借鉴了AspectJ的切面,以提供注解驱动的AOP。这种AOP风格的好处是能够不使用XML来配置。

Spring中的AOP
Spring在运行时通知对象。也就是说Spring不会在编译器或者类加载期完成织入。通过在代理类中包裹切面,Spring在运行期把切面织入到Spring管理的bean中。代理类会封装目标类,并且拦截被通知党法的调用。

Spring只支持方法级别的连接点。

2,通过切点来选择连接点

在Spring AOP中,使用AspectJ的切点表达式语言来定义切点。Spring只支持AspectJ切点指示器(pointcut designator)的一个子集,这里要深入理解需要参考AspectJ的相关资料。在Spring支持的指示器中,只有execution指示器是实际执行匹配的,而其他的指示器都是用来限制匹配的。

2.1,编写切点

先定义一个接口:

package concert;
public interface Performance{
    public void perform();
}

这里写图片描述

如图所示,使用execution()指示器选择Performance的perform()方法。方法表达式以“*”开始,表明可以返回任意类型。类名需要使用全限定类型,方法的参数列表使用两个点号表明切点要选择任意的perform()方法,因为可能存在多个重载的perform()方法。

这里写图片描述
如图所示为使用within()指示器的样例。

Spring引入了一个新的bean()指示器,它允许我们在切点表达式中使用bean的ID来标识bean。bean()使用bean ID或bean名称作为参数来限制切点只匹配特定的bean。例如:

execution(* concert.Performance.perform()) and bean('woodstock')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值