Spring AOP配置与治理的补充—环绕通知
Spring AOP配置与管理的补充—环绕通知
Spring AOP 之 环绕通知
Spring AOP 之 环绕通知
在所有的通知类型中,环绕通知最为强大。因为它能完全控制方法的执行过程,所以可以把前一篇文章中所有通知动作都合并到一个单独的通知里。甚至可以控制是否以及何时继续执行原始方法。
在Spring AOP中,环绕通知必须实现MethodInterceptor接口。这个接口是AOP联盟为了保持不同AOP框架之间的兼容性而定义的。当编写环绕通知时,必须记住——如果要继续执行原始方法,那么就必须调用methodInvocation.proceed()。如果忘记执行这一步,那么原始方法将不会被调用。下面的环绕通知合并了前面所创建的前置、后置和异常通知。
package org.mahz.easyaop.calculator.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class LoggingAroundAdvice implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { String methodName = invocation.getMethod().getName(); printTitle(methodName); System.out.println("The method " + methodName + "()begin with " + Arrays.toString(invocation.getArguments())); try { Object returnValue = invocation.proceed(); System.out.println("The Method " + methodName + "() ends with " + returnValue); return returnValue; } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); throw e; } } private void printTitle(String methodName) { System.out.println("=========================================="); System.out.println("============ Test " + methodName + " Method ============="); System.out.println("=========================================="); } }
环绕通知类型非常强大、非常灵活,你甚至可以改变原始的方法参数值以及最终的返回结果。但是因为很容易忘记执行原始的方法,所以在使用这种通知时必须非常小心。
因为这个通知结合了前面所有通知,所以只需要为代理指定这一个通知即可。
<bean id="arithmeticCalculator" class="org.mahz.easyaop.calculator.impl.ArithmeticCalculatorImpl" /> <bean id="unitCalculator" class="org.mahz.easyaop.calculator.impl.UnitCalculatorImpl" /> <!-- <bean id="logginBeforeAdvice" class="org.mahz.easyaop.calculator.aop.LoggingBeforeAdvice" /> <bean id="logginAfterAdvice" class="org.mahz.easyaop.calculator.aop.LoggingAfterAdvice" /> <bean id="logginThrowsAdvice" class="org.mahz.easyaop.calculator.aop.LoggingThrowsAdvice" /> --> <bean id="logginAroundAdvice" class="org.mahz.easyaop.calculator.aop.LoggingAroundAdvice" /> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>*Calculator</value> </list> </property> <property name="interceptorNames"> <list> <!-- <value>logginBeforeAdvice</value> <value>logginAfterAdvice</value> <value>logginThrowsAdvice</value> --> <value>logginAroundAdvice</value> </list> </property> </bean>
执行结果:
========================================== ============ Test add Method ============= ========================================== The method add()begin with [4.0, 0.0] 4.0 + 0.0 = 4.0 The Method add() ends with 4.0 ========================================== ============ Test sub Method ============= ========================================== The method sub()begin with [4.0, 0.0] 4.0 - 0.0 = 4.0 The Method sub() ends with 4.0 ========================================== ============ Test mul Method ============= ========================================== The method mul()begin with [4.0, 0.0] 4.0 * 0.0 = 0.0 The Method mul() ends with 0.0 ========================================== ============ Test div Method ============= ========================================== The method div()begin with [4.0, 0.0] Division by zero