Spring:AOP通知执行顺序
1. AOP的通知
- Before、After、AfterReturning、AfterThrowing、Around
2. AOP通知的执行顺序
- 切面代码:
package com.itlearn.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; public class AccountAspect { public void printAcc(){ } public void before(){ System.out.println("before..."); } public void after(){ System.out.println("after..."); } public void afterRunning(){ System.out.println("afterReturning..."); } public void afterThrowing(){ System.out.println("afterThrowing..."); } public void around(ProceedingJoinPoint joinPoint){ System.out.println("around before"); try{ joinPoint.proceed();//调用切入点的方法 }catch (Throwable throwable){ new RuntimeException("回调原有函数,产生异常..."); } System.out.println("around after"); } }
- xml配置如下:
<bean id="accountAspect" class="com.itlearn.aspect.AccountAspect"></bean> <!-- 配置启用AspectJ框架的自动代理,这时Spring框架才会生成动态代理对象,进而可以使用AOP proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。--> <aop:aspectj-autoproxy proxy-target-class="true"/> <aop:config > <aop:aspect id="accountAspect" ref="accountAspect"> <aop:pointcut id="printAcc" expression="execution(* com.itlearn.service.impl.IAccountServiceImpl.printAccount(..))"/> <aop:before method="before" pointcut-ref="printAcc"/> <aop:after method="after" pointcut-ref="printAcc"/> <aop:after-returning method="afterRunning" pointcut-ref="printAcc"/> <aop:after-throwing method="afterThrowing" pointcut-ref="printAcc"/> <aop:around method="around" pointcut-ref="printAcc"></aop:around> </aop:aspect> </aop:config>
- 切点
package com.itlearn.service.impl; import com.itlearn.dao.IAccountDao; import com.itlearn.domain.Account; import com.itlearn.service.IAccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import java.util.List; @Service("accountService") public class IAccountServiceImpl implements IAccountService { @Override public void printAccount() { try { // int i = 10/0; System.out.println("打印Account..."); }catch (Exception ex){ ex.printStackTrace(); } } }
- 测试结果:
before... around before 打印Account... around after afterReturning... after...
3. 结论
AOP通知执行顺序:before-[around before]-切点方法-[around after]-afterReturning-after