AOP示例(续)

上一篇演示了,Spring得前通知、后通知、环绕通知,仔细想来前通知、后通知和异常通知,都应该是居于环绕通知开发的,想想如果都能控制目标函数是否能执行,那么要在目标函数执行前后,或者目标函数执行过程中发生异常后进行一些处理,那不是太easy了吗?,按照猜想,前通知、后通知,异常通知 应该是重写invoke方法,在invoke方法里面先执行before在执行proceed就是前通知,先执行proceed在执行afterReturning就是后通知,用在try 里面执行invoke方法就是异常通知。我下面来看spring的源码进行验证

  1. /*
  2.  * Copyright 2002-2007 the original author or authors.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package org.springframework.aop.framework.adapter;
  17. import java.io.Serializable;
  18. import org.aopalliance.intercept.MethodInterceptor;
  19. import org.aopalliance.intercept.MethodInvocation;
  20. import org.springframework.aop.MethodBeforeAdvice;
  21. import org.springframework.util.Assert;
  22. /**
  23.  * Interceptor to wrap am {@link org.springframework.aop.MethodBeforeAdvice}.
  24.  * Used internally by the AOP framework; application developers should not need
  25.  * to use this class directly.
  26.  *
  27.  * @author Rod Johnson
  28.  */
  29. public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
  30.     private MethodBeforeAdvice advice;
  31.     /**
  32.      * Create a new MethodBeforeAdviceInterceptor for the given advice.
  33.      * @param advice the MethodBeforeAdvice to wrap
  34.      */
  35.     public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
  36.         Assert.notNull(advice, "Advice must not be null");
  37.         this.advice = advice;
  38.     }
  39.     public Object invoke(MethodInvocation mi) throws Throwable {
  40.         this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
  41.         return mi.proceed();
  42.     }
  43. }
  1. /*
  2.  * Copyright 2002-2007 the original author or authors.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package org.springframework.aop.framework.adapter;
  17. import java.io.Serializable;
  18. import org.aopalliance.intercept.MethodInterceptor;
  19. import org.aopalliance.intercept.MethodInvocation;
  20. import org.springframework.aop.AfterAdvice;
  21. import org.springframework.aop.AfterReturningAdvice;
  22. import org.springframework.util.Assert;
  23. /**
  24.  * Interceptor to wrap am {@link org.springframework.aop.AfterReturningAdvice}.
  25.  * Used internally by the AOP framework; application developers should not need
  26.  * to use this class directly.
  27.  *
  28.  * @author Rod Johnson
  29.  */
  30. public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
  31.     private final AfterReturningAdvice advice;
  32.     /**
  33.      * Create a new AfterReturningAdviceInterceptor for the given advice.
  34.      * @param advice the AfterReturningAdvice to wrap
  35.      */
  36.     public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
  37.         Assert.notNull(advice, "Advice must not be null");
  38.         this.advice = advice;
  39.     }
  40.     public Object invoke(MethodInvocation mi) throws Throwable {
  41.         Object retVal = mi.proceed();
  42.         this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
  43.         return retVal;
  44.     }
  45. }
  1. /*
  2.  * Copyright 2002-2007 the original author or authors.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package org.springframework.aop.framework.adapter;
  17. import java.lang.reflect.InvocationTargetException;
  18. import java.lang.reflect.Method;
  19. import java.util.HashMap;
  20. import java.util.Map;
  21. import org.aopalliance.intercept.MethodInterceptor;
  22. import org.aopalliance.intercept.MethodInvocation;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import org.springframework.aop.AfterAdvice;
  26. import org.springframework.util.Assert;
  27. /**
  28.  * Interceptor to wrap an after-throwing advice.
  29.  *
  30.  * <p>The signatures on handler methods on the <code>ThrowsAdvice</code>
  31.  * implementation method argument must be of the form:<br>
  32.  *
  33.  * <code>void afterThrowing([Method, args, target], ThrowableSubclass);</code>
  34.  *
  35.  * <p>Only the last argument is required.
  36.  *
  37.  * <p>Some examples of valid methods would be:
  38.  *
  39.  * <pre class="code">public void afterThrowing(Exception ex)</pre>
  40.  * <pre class="code">public void afterThrowing(RemoteException)</pre>
  41.  * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre>
  42.  * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre>
  43.  *
  44.  * <p>This is a framework class that need not be used directly by Spring users.
  45.  *
  46.  * @author Rod Johnson
  47.  * @author Juergen Hoeller
  48.  */
  49. public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
  50.     private static final String AFTER_THROWING = "afterThrowing";
  51.     private static final Log logger = LogFactory.getLog(ThrowsAdviceInterceptor.class);
  52.     private final Object throwsAdvice;
  53.     /** Methods on throws advice, keyed by exception class */
  54.     private final Map exceptionHandlerMap = new HashMap();
  55.     /**
  56.      * Create a new ThrowsAdviceInterceptor for the given ThrowsAdvice.
  57.      * @param throwsAdvice the advice object that defines the exception
  58.      * handler methods (usually a {@link org.springframework.aop.ThrowsAdvice}
  59.      * implementation)
  60.      */
  61.     public ThrowsAdviceInterceptor(Object throwsAdvice) {
  62.         Assert.notNull(throwsAdvice, "Advice must not be null");
  63.         this.throwsAdvice = throwsAdvice;
  64.         Method[] methods = throwsAdvice.getClass().getMethods();
  65.         for (int i = 0; i < methods.length; i++) {
  66.             Method method = methods[i];
  67.             if (method.getName().equals(AFTER_THROWING) &
  68.                     //m.getReturnType() == null &&
  69.                     (method.getParameterTypes().length == 1 || method.getParameterTypes().length == 4) &
  70.                     Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])
  71.                 ) {
  72.                 // Have an exception handler
  73.                 this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length - 1], method);
  74.                 if (logger.isDebugEnabled()) {
  75.                     logger.debug("Found exception handler method: " + method);
  76.                 }
  77.             }
  78.         }
  79.         
  80.         if (this.exceptionHandlerMap.isEmpty()) {
  81.             throw new IllegalArgumentException(
  82.                     "At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
  83.         }
  84.     }
  85.     
  86.     public int getHandlerMethodCount() {
  87.         return this.exceptionHandlerMap.size();
  88.     }
  89.     /**
  90.      * Determine the exception handle method. Can return null if not found.
  91.      * @param exception the exception thrown
  92.      * @return a handler for the given exception type
  93.      */
  94.     private Method getExceptionHandler(Throwable exception) {
  95.         Class exceptionClass = exception.getClass();
  96.         if (logger.isTraceEnabled()) {
  97.             logger.trace("Trying to find handler for exception of type [" + exceptionClass.getName() + "]");
  98.         }
  99.         Method handler = (Method) this.exceptionHandlerMap.get(exceptionClass);
  100.         while (handler == null && !exceptionClass.equals(Throwable.class)) {
  101.             exceptionClass = exceptionClass.getSuperclass();
  102.             handler = (Method) this.exceptionHandlerMap.get(exceptionClass);
  103.         }
  104.         if (handler != null && logger.isDebugEnabled()) {
  105.             logger.debug("Found handler for exception of type [" + exceptionClass.getName() + "]: " + handler);
  106.         }
  107.         return handler;
  108.     }
  109.     public Object invoke(MethodInvocation mi) throws Throwable {
  110.         try {
  111.             return mi.proceed();
  112.         }
  113.         catch (Throwable ex) {
  114.             Method handlerMethod = getExceptionHandler(ex);
  115.             if (handlerMethod != null) {
  116.                 invokeHandlerMethod(mi, ex, handlerMethod);
  117.             }
  118.             throw ex;
  119.         }
  120.     }
  121.     
  122.     private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {
  123.         Object[] handlerArgs;
  124.         if (method.getParameterTypes().length == 1) {
  125.             handlerArgs = new Object[] { ex };
  126.         }
  127.         else {
  128.             handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
  129.         }
  130.         try {
  131.             method.invoke(this.throwsAdvice, handlerArgs);
  132.         }
  133.         catch (InvocationTargetException targetEx) {
  134.             throw targetEx.getTargetException();
  135.         }
  136.     }
  137. }

通过spring的源码可以确定刚刚的想法。现在明白了前通知和后通知,异常通知是怎么实现的了,但是问题又来了,怎么在我调用业务方法的前去执行invoke方法呢?看来还要继续研究一下^_^

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值