Spring给通知传递参数
1. spring-aop中为通知传递参数
- 切点
@Override public void printAccount(Account account) { try { // int i = 10/0; System.out.println("打印Account..."); }catch (Exception ex){ ex.printStackTrace(); }
- 切面
package com.itlearn.aspect; import com.itlearn.domain.Account; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; //定义此类为一个切面:内含各种通知 //@Aspect public class AccountAspect { // @Pointcut("execution(* com.itlearn.service.impl.IAccountServiceImpl.printAccount(..))") public void printAcc(){ } //@Before("printAcc()") public void before(){ System.out.println("before..."); } //@After("printAcc()") public void after(Account account){ System.out.println("after..."); } //@AfterReturning("printAcc()") public void afterReturining(Account account){ System.out.println(account); System.out.println("afterReturning..."); } //@AfterThrowing("printAcc()") 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"); } }
可见:afterReturining和after通知都有参数要求。
- xml配置通知
<bean id="accountAspect" class="com.itlearn.aspect.AccountAspect"></bean> <!-- 配置启用AspectJ框架的自动代理,这时Spring框架才会生成动态代理对象,进而可以使用AOP 配置proxy-target-class="true" --> <aop:aspectj-autoproxy proxy-target-class="true"/> <aop:config > <aop:aspect id="accountAspect" ref="accountAspect"> <aop:pointcut id="printAcc" expression="execution(* com.itlearn.service.IAccountService.printAccount(..))"/> <aop:before method="before" pointcut-ref="printAcc"/> <aop:after method="after" pointcut="execution(* com.itlearn.service.IAccountService.printAccount(..)) and args(account)"/> <aop:after-returning method="afterReturining" pointcut="execution(* com.itlearn.service.IAccountService.printAccount(..)) and args(account)"/> <aop:after-throwing method="afterThrowing" pointcut-ref="printAcc"/> <aop:around method="around" pointcut-ref="printAcc"/> </aop:aspect> </aop:config>
可见:before、after-throwing、around都是使用的切入点,而带参数的两个通知则使用的是自己配置的带参的切点。
- 运行结果
before... around before 打印Account... around after Account{ID=1, UID=2, MONEY=1000.0} afterReturning... after...
2. 结论
<aop:after method="after" pointcut="execution(* com.itlearn.service.IAccountService.printAccount(..)) and args(account)"/>
注意:
- and的使用。
- args(account)中参数account要和接口参数名一致,否则无法识别。