1 16 17 package org.springframework.aop.framework.adapter; 18 19 import java.lang.reflect.InvocationTargetException ; 20 import java.lang.reflect.Method ; 21 import java.util.HashMap ; 22 import java.util.Map ; 23 24 import org.aopalliance.intercept.MethodInterceptor; 25 import org.aopalliance.intercept.MethodInvocation; 26 import org.apache.commons.logging.Log; 27 import org.apache.commons.logging.LogFactory; 28 29 import org.springframework.aop.AfterAdvice; 30 import org.springframework.util.Assert; 31 32 54 public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice { 55 56 private static final String AFTER_THROWING = "afterThrowing"; 57 58 private static final Log logger = LogFactory.getLog(ThrowsAdviceInterceptor.class); 59 60 61 private final Object throwsAdvice; 62 63 64 private final Map exceptionHandlerMap = new HashMap (); 65 66 67 73 public ThrowsAdviceInterceptor(Object throwsAdvice) { 74 Assert.notNull(throwsAdvice, "Advice must not be null"); 75 this.throwsAdvice = throwsAdvice; 76 77 Method [] methods = throwsAdvice.getClass().getMethods(); 78 for (int i = 0; i < methods.length; i++) { 79 Method method = methods[i]; 80 if (method.getName().equals(AFTER_THROWING) && 81 (method.getParameterTypes().length == 1 || method.getParameterTypes().length == 4) && 83 Throwable .class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1]) 84 ) { 85 this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length - 1], method); 87 if (logger.isDebugEnabled()) { 88 logger.debug("Found exception handler method: " + method); 89 } 90 } 91 } 92 93 if (this.exceptionHandlerMap.isEmpty()) { 94 throw new IllegalArgumentException ( 95 "At least one handler method must be found in class [" + throwsAdvice.getClass() + "]"); 96 } 97 } 98 99 public int getHandlerMethodCount() { 100 return this.exceptionHandlerMap.size(); 101 } 102 103 108 private Method getExceptionHandler(Throwable exception) { 109 Class exceptionClass = exception.getClass(); 110 if (logger.isTraceEnabled()) { 111 logger.trace("Trying to find handler for exception of type [" + exceptionClass.getName() + "]"); 112 } 113 Method handler = (Method ) this.exceptionHandlerMap.get(exceptionClass); 114 while (handler == null && !exceptionClass.equals(Throwable .class)) { 115 exceptionClass = exceptionClass.getSuperclass(); 116 handler = (Method ) this.exceptionHandlerMap.get(exceptionClass); 117 } 118 if (handler != null && logger.isDebugEnabled()) { 119 logger.debug("Found handler for exception of type [" + exceptionClass.getName() + "]: " + handler); 120 } 121 return handler; 122 } 123 124 public Object invoke(MethodInvocation mi) throws Throwable { 125 try { 126 return mi.proceed(); 127 } 128 catch (Throwable ex) { 129 Method handlerMethod = getExceptionHandler(ex); 130 if (handlerMethod != null) { 131 invokeHandlerMethod(mi, ex, handlerMethod); 132 } 133 throw ex; 134 } 135 } 136 137 private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable { 138 Object [] handlerArgs; 139 if (method.getParameterTypes().length == 1) { 140 handlerArgs = new Object [] { ex }; 141 } 142 else { 143 handlerArgs = new Object [] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex}; 144 } 145 try { 146 method.invoke(this.throwsAdvice, handlerArgs); 147 } 148 catch (InvocationTargetException targetEx) { 149 throw targetEx.getTargetException(); 150 } 151 } 152 153 } 154 | Popular Tags |