4种定义切面的方式:
1)基于@AspectJ注解的方式:
2)基于<aop:aspect>的方式;
3)基于<aop:advisor>的方式;
4)基于Advisor类的方式。
如果项目采用JDK5.0,可以优先考虑使用@AspectJ;如果项目只能使用低版本的JDK,则可以考虑使用<aop:aspect>;如果正在升级一个基于低版本Spring AOP开发的项目,则可以考虑使用<aop:advisor>复用已经存在的Advice类;如果项目只能使用低版本的Spring,那么就只能使用Advisor了。此外,值得注意的是一些切面只能使用基于API的Advisor方式进行构建,如基于ControlFlowPointcut的流程切面。
各种切面类型总结:
@AspectJ | <aop:aspect> | Advisor | <aop:advisor> | ||
增 强 类 型 |
前置增强 | @Before | <aop:before> | MethodBeforeAdvice | 同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>相同,不过切点函数不能绑定参数 | |
连接点方法入参绑定 | 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:advisor>其实是<aop:aspect>和Advisor的混血儿,它的切点表示方法和<aop:aspect>相同,增强定义方式则和Advisor相同。连接点方法入参的绑定方式和Advisor一样,通过增强接口方法入参进行调用,所以<aop:advisor>在切点表达式中,需要注意不能使用切点函数绑定连接点方法入参,否则会产生错误。