Spring的AOP动态调用的反思
以往做项目的时候,用到了SPRING的AOP来做权限拦截。但项目里用的是Strut1,用的最多的Action是DispatchAction。所配置好一切以后,竟然发现不能有效的拦截DispatchAction里的各个方法。通过对DispatchAction源码的查看,发现原来DispatchAction是通过动态调用来执行各个不同的方法的~
代码如下:
public abstract class DispatchAction extends BaseAction/* */ {/* 98 */ protected static Log log = LogFactory.getLog(DispatchAction.class);/* */ protected Class clazz;/* */ protected HashMap methods;/* */ protected Class[] types;/* */ /* */ public DispatchAction()/* */ {/* 105 */ this.clazz = super.getClass();/* */ /* 113 */ this.methods = new HashMap();/* */ /* 119 */ this.types = new Class[] { ActionMapping.class, ActionForm.class, HttpServletRequest.class, HttpServletResponse.class };/* */ }/* */ /* */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)/* */ throws Exception/* */ { //首先执行这里,程序的入口/* 145 */ if (isCancelled(request)) {/* 146 */ ActionForward af = cancelled(mapping, form, request, response);/* */ /* 148 */ if (af != null) {/* 149 */ return af;/* */ }/* */ /* */ }/* */ /* 154 */ String parameter = getParameter(mapping, form, request, response); //获取strut配置文件中的parameter的参数--通常为method/* */ /* 157 */ String name = getMethodName(mapping, form, request, response, parameter);/* */ /* 161 */ if (("execute".equals(name)) || ("perform".equals(name))) {/* 162 */ String message = messages.getMessage("dispatch.recursive", mapping.getPath());/* */ /* 165 */ log.error(message);/* 166 */ throw new ServletException(message);/* */ }/* */ /* 170 */ return dispatchMethod(mapping, form, request, response, name); //根据method动态调用方法/* */ }/* */ /* */ protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)/* */ throws Exception/* */ {/* 191 */ String message = messages.getMessage("dispatch.parameter", mapping.getPath(), mapping.getParameter());/* */ /* 195 */ log.error(message);/* */ /* 197 */ throw new ServletException(message);/* */ }/* */ /* */ protected ActionForward cancelled(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)/* */ throws Exception/* */ {/* 219 */ return null;/* */ }/* */ /* */ protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String name)/* */ throws Exception/* */ {/* 244 */ if (name == null) {/* 245 */ return unspecified(mapping, form, request, response);/* */ }/* */ /* 249 */ Method method = null;/* */ try/* */ {/* 252 */ method = getMethod(name);/* */ } catch (NoSuchMethodException e) {/* 254 */ String message = messages.getMessage("dispatch.method", mapping.getPath(), name);/* */ /* 257 */ log.error(message, e);/* */ /* 259 */ String userMsg = messages.getMessage("dispatch.method.user", mapping.getPath());/* */ /* 261 */ throw new NoSuchMethodException(userMsg);/* */ }/* */ /* 264 */ ActionForward forward = null;/* */ try/* */ {/* 267 */ Object[] args = { mapping, form, request, response };/* */ /* 269 */ forward = (ActionForward)method.invoke(this, args); //这里就是通过动态的调用,来执行各个方法的/* */ } catch (ClassCastException e) {/* 271 */ String message = messages.getMessage("dispatch.return", mapping.getPath(), name);/* */ /* 274 */ log.error(message, e);/* 275 */ throw e;/* */ } catch (IllegalAccessException e) {/* 277 */ String message = messages.getMessage("dispatch.error", mapping.getPath(), name);/* */ /* 280 */ log.error(message, e);/* 281 */ throw e;/* */ }/* */ catch (InvocationTargetException e)/* */ {/* 285 */ Throwable t = e.getTargetException();/* */ /* 287 */ if (t instanceof Exception) {/* 288 */ throw ((Exception)t);/* */ }/* 290 */ String message = messages.getMessage("dispatch.error", mapping.getPath(), name);/* */ /* 294 */ log.error(message, e);/* 295 */ throw new ServletException(t);/* */ }/* */ /* 300 */ return forward;/* */ }/* */ /* */ protected String getParameter(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)/* */ throws Exception/* */ {/* 318 */ String parameter = mapping.getParameter();/* */ /* 320 */ if (parameter == null) {/* 321 */ String message = messages.getMessage("dispatch.handler", mapping.getPath());/* */ /* 324 */ log.error(message);/* */ /* 326 */ throw new ServletException(message);/* */ }/* */ /* 330 */ return parameter;/* */ }/* */ /* */ protected Method getMethod(String name)/* */ throws NoSuchMethodException/* */ {/* 344 */ synchronized (this.methods) {/* 345 */ Method method = (Method)this.methods.get(name);/* */ /* 347 */ if (method == null) {/* 348 */ method = this.clazz.getMethod(name, this.types);/* 349 */ this.methods.put(name, method);/* */ }/* */ /* 352 */ return method;/* */ }/* */ }/* */ /* */ protected String getMethodName(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String parameter)/* */ throws Exception/* */ {/* 374 */ return request.getParameter(parameter);/* */ }/* */ }@Component("aspectDemo")@Aspectpublic class AspectDemo {// 定义切入点表达式private final static String EXP = "execution(* cn.gs..*.*(..))";@Around(EXP)public Object around(ProceedingJoinPoint point) throws Throwable {System.out.println("Around Before " + point.getSignature().getName());// 调用目标对象的方法并获取返回值Object o = point.proceed(point.getArgs());System.out.println("Around After " + point.getSignature().getName());return o;}}@Service("dynamicProxy")public class DynamicProxy {public Object withMethodToExecute(String name) throws Exception { // 调用了withMethodToExecuteMethod method = getMethod(name);Object obj = method.invoke(this, name); // 此处动态调用了method1return obj;}public Object withMethodToExecute2(String name) throws Exception { // 调用了withMethodToExecutemethod1(""); //直接调用method1return null;}public String method1(String methodName) {System.out.println(" execute method1");return methodName;}public Method getMethod(String name) throws NoSuchMethodException {Method method = this.getClass().getMethod(name, String.class);return method;}}<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <aop:aspectj-autoproxy/><context:component-scan base-package="cn.gs"/> </beans>
public class ManTest {static DynamicProxy dynamicProxy;@BeforeClasspublic static void setUpBeforeClass() throws Exception {try {ApplicationContext act = new ClassPathXmlApplicationContext("beans.xml");dynamicProxy = (DynamicProxy) act.getBean("dynamicProxy");} catch (RuntimeException e) {e.printStackTrace();}}@Testpublic void testSay() throws Exception {dynamicProxy.withMethodToExecute("method1"); //动态调用method1System.out.println("============================="); dynamicProxy.withMethodToExecute2("method1"); //直接调用method1System.out.println("ok"); }}