1 简介
1.1 概述
AOP(Aspect Oriented Programming),即面向切面编程,是一种新的方法论,是对传统面向对象编程(OOP Object Oriented Programming)的补充。
AOP编程操作的主要对象是切面(Aspect),切面模块化了横切关注点。
1.2 好处
每个事物逻辑位于一个位置,代码不分散,便于维护和升级。
业务模块更简洁,只包含核心业务代码。
1.3 方式
使用基于注解的方式来实现,也可以使用基于XML的配置来实现。正常情况下,基于注解的声明要优先于基于XML的声明。
1.4 底层原理
AOP底层使用动态代理,有接口的情况下使用JDK动态代理,没有接口的情况下使用CGLIB的动态代理。
JDK动态代理通过创建接口实现类的代理对象实现动态代理,CGLIB动态代理通过创建子类的代理对象实现动态代理。
2 术语
2.1 横切关注点
从每个方法中抽取出来的非核心业务,每个方法往往有多个横切关注点,比如:方法开始前、方法正常返回后、方法出现异常后、方法最终结束后。
2.2 切面类(Aspect)
封装横切关注点和通知方法的类。
2.2.1 切面的优先级
如果在同一个连接点上应用了不止一个切面时,除非明确指定,否则切面的优先级是不确定的。
2.3 连接点(JoinPoint)
横切关注点在程序代码中的具体体现,对应程序执行的某个特定位置。例如:方法调用前、调用后、方法捕获到异常后、方法结束后等。
在应用程序中可以使用业务方法和业务方法的横切关注点定位一个具体的连接点。
2.3.1 获取当前连接点信息
切面类中的通知方法能根据注解和注解的值来定位连接点,在通知方法中也就可以获取到当前连接点的一些信息。
连接点信息都封装在JoinPoint接口的实例对象中,可以通过JoinPoint获取业务方法的详细信息。
只需要在通知方法的传入参数中声明这个参数,当执行通知方法时会自动的将业务方法的详细信息封装在JoinPoint对象中。
public void work(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();// 获取方法名
Object[] args = joinPoint.getArgs();// 获取方法的参数列表
}
2.4 切入点(Pointcut)
定位连接点的方式,每个类的方法中都包含多个连接点,选中的连接点被称为切入点。
如果把连接点看作数据库中的记录,那么切入点就是查询条件,AOP可以通过切入点定位到特定的连接点。
2.4.1 切入点表达式
通过表达式的方式定位一个或多个具体的连接点。
2.4.2 语法格式
execution([权限修饰符] [返回值类型] [简单类名/全类名] [方法名]([参数列表]))
在AspectJ中,切入点表达式可以通过 “&&”、“||”、“!”等操作符结合起来。
2.4.3 参数说明
1)权限修饰符可以省略,省略表示匹配所有。
2)返回值类型不能省略,使用“*”表示匹配所有返回值类型。
3)类名不能省略,使用“*”表示匹配所有类名。
4)方法名不能省略,使用“*”表示匹配所有方法。
5)参数列表不能省略,使用“..”表示匹配任意数量、任意类型的参数。
2.5 通知方法(Advice)
在横切关注点要执行的动作,封装为方法,一个横切关注点对应一个通知方法。
一套通知方法组成一个切面。
2.5.1 前置通知Before
在方法执行之前执行的通知。
2.5.2 后置通知After
在方法执行之后执行的通知,即返回结果之后或者抛出异常之后。
2.5.3 返回通知AfterReturning
只有方法执行并正常返回之后才执行的通知,如果出现异常则不会执行。
如果要在返回通知中使用方法执行返回的结果,需要使用returning属性,并在通知方法的传入参数中添加一个同名参数。
2.5.4 异常通知AfterThrowing
只有方法执行并抛出异常之后才执行的通知。
如果要在异常通知中得到方法执行抛出的异常,需要使用throwing属性,并在通知方法的传入参数中添加一个同名参数。
如果只对某种异常类型感兴趣,可以声明为此异常的参数类型,通知就只在抛出这个类型及其子类的异常时才被执行。
2.5.5 环绕通知Around
环绕通知是所有通知类型中功能最为强大的,能够全面地控制连接点,甚至可以控制是否执行连接点。
可以将环绕通知看做业务方法的动态代理。
通知方法的参数类型必须是ProceedingJoinPoint类型的实例,ProceedingJoinPoint是JoinPoint的子接口。需要明确调用ProceedingJoinPoint实例的proceed()方法来执行被代理的方法,否则会导致通知被执行,但业务方法没有被执行。
3 导包
3.1 核心
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
3.2 依赖
commons-logging-1.1.3.jar
3.3 AOP注解
spring-aop-4.0.0.RELEASE.jar
3.4 AspectJ工具
spring-aspects-4.0.0.RELEASE.jar
3.5 AspectJ动态代理
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar