基本概念
Aspect(切面) |
切面类,面向切面编程的主体类,用以定义Pointcut和Advice这样的对应关系。 由切点和增强(引介)组成,横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象(把增强应用到具体方法的过程叫做切面),横切逻辑和连接点的定义 |
JoinPoint (切入点/连接点) |
切入点,程序执行的某个特定位置,如类某个方法调用前、调用后、方法抛出异常后等。 连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。 |
Advice(增强/通知) |
Aspect需要在JoinPoint处执行的操作。很多AOP框架会把Advice以类似于Interceptor(拦截器)的形式进行封装,然后在每个Join Point的前后都可以包含一个Interceptor链,即可以进行多个操作处理。 Advice就是切面必须要完成的工作(增强的逻辑,如扩展日志功能,这个功能就叫做增强,Advice分为前置。后置。异常。最终。环绕通知等) |
Pointcut(切点) |
用来定义匹配的Join Point,它是一个表达式。往往跟Advice绑定在一起,用以指定需要在Pointcut表达式匹配的JoinPoint执行的操作。采用Pointcut表达式来匹配JoinPoint能够使得的Advice能够比较独立,即一个Advice可以同时服务于多个JoinPoint。 Spring AOP默认采用Aspectj的Pointcut表达式。 每个类都拥有多个连接点,连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。 切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。(类中有很多方法可以被增强,实际中被增强的方法叫做切入点) |
Introduction(引介) |
用来声明额外的方法和属性。可以给目标对象引入新的接口及其实现。例如可以使用Introduction让一个bean实现isModified接口。 特殊的增强,为类添加属性和方法 |
Target(目标对象) |
表示Aspect正在处理的对象。因为Spring AOP是基于运行时代理实现的,所以这个对象永远都是一个代理对象。被通知的对象(需要增强的类) |
Proxy |
向目标对象应用通知之后创建的对象。由AOP框架创建的一个代理对象。这个代理对象将由JDK代理或CGLIB代理生成 一个类被AOP织入增强后,就产生一个结果类(融合了原类和增强逻辑的代理类),根据不同的代理方式,代理类既可能是和原类具有相同的接口的类,也可能是原类的子类 |
Weaving织入 |
用以将切面类Aspect与目标对象联系在一起的这么一个动作,所形成的结果就是在Pointcut所指定的Join Point执行时由Aspect对目标对象执行特定的Advice。 AOP框架中的Weaving动作可以发生在编译时、类装载时和运行时,Spring AOP的Weaving动作是发生在运行时 将增强添加到目标类的具体连接点上的过程 ,AOP有3中织入方式:1.编译期织入,需要使用特殊的Java编译器。2.类装载期织入:要求使用特殊的类装载器。3.动态代理织入:在运行期为目标类添加增强生成子类的方法。Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入 |
Advice类型
切面四种不同定义方式的具体实现:
@AspectJ注解 |
<aop:aspect> |
Advisor接口 |
<aop:advisor> |
||
增强类型 |
前置增强 |
@Before |
<aop:before> |
MethodBeforAdvice |
同Advisor |
后置增强 |
@AfterReturning |
<aop:after-returning> |
AfterReturningAdvice |
同Advisor |
|
环绕增强 |
@Around |
<aop:around> |
MethodInterceptor |
同Advisor |
|
抛出异常增强 |
@AfterThrowing |
<aop:after-throwing> |
ThrowsAdvice |
同Advisor |
|
Final增强 |
@After |
<aop:after> |
无 |
同Advisor |
|
引介增强 |
@DeclareParents |
<aop:declare-parents> |
IntroductionInterceptor |
同Advisor |
|
切点定义 |
支持AspectJ切点表达式语法,可通过@Pointcut注解定义命名切点 |
支持AspectJ切点表达式语法,可通过<aop:pointcut>定义命名切点 |
直接通过基于Pointcut实现类定义切点 |
和<aop:aspect>相似,但是切点函数不能绑定参数 |
|
切面定义 |
切面只是一个带有 @Aspect 注解的 Java 类,Spring就知道他是一个切面(必须是被spring管理的) |
||||
连接点方法入参绑定 |
1)使用JoinPoint、ProceedingJoinPoint连接点对象 2)使用切点函数指定参数名绑定 |
同@AspectJ <aop:after-returning> |
通过增强接口方法入参绑定 |
同Advisor |
|
连接点方法返回值或抛出异常绑定 |
1)在后置增强中,使用@AfterReturning的returning成员绑定方法返回值 2)在抛出异常增强中,使用@AfterThrowing的throwing成员绑定方法抛出的异常 |
1)在后置增强中,使用<aop:after-returning>的returning属性绑定方法返回值 2)在抛出异常增强中,使用<aop:after-throwing>的throwing属性绑定方法抛出的异常 |
通过增强接口方法入参绑定 |
同Advisor |
|
<aop:aspectj-autoproxy/>标签, <aop:advisor> 定义一个AOP通知者 <aop:after> 后通知 <aop:after-returning> 返回后通知 <aop:after-throwing> 抛出后通知 <aop:around> 周围通知 <aop:aspect>定义一个切面 <aop:before>前通知 <aop:config>顶级配置元素,类似于<beans>这种东西 <aop:pointcut>定义一个切点 |
|||||
要求 |
必须是JDK5以上版本,因为是注解。 非JDK5项目,可通过基于Schema的配置定义切面【xml】 |
将 aop Schema 添加到 <beans> 根元素中.在 Bean 配置文件中定义一个空的 XML 元素 <aop:aspectj-autoproxy> 当 Spring IOC 容器侦测到 Bean 配置文件中的 <aop:aspectj-autoproxy> 元素时, 会自动为与 AspectJ 切面匹配的 Bean 创建代理. |
|||
优点 |
非常容易定义一个切面,不需要实现任何接口 |
||||
缺点 |