Xwork2 源码阅读(三)

接着看Dispatcher

 

           ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
                    namespace, name, extraContext, true, false);

 

用Container 构造一个 ActionProxyFactory,在用ActionProxyFactory create一个 ActionProxy。

 

    public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) {
        
        ActionInvocation inv = new DefaultActionInvocation(extraContext, true);
        container.inject(inv);
        return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
    }

 

 

xwork中,action的调用是借助 Proxy 模式,

Proxy 模式的实现,则是 DefaultActionProxy, Action, ActionInvocation 合伙完成的。

下边是一些关键代码

 

DefaultActionProxy

 

    public String execute() throws Exception {
        ActionContext nestedContext = ActionContext.getContext();
        ActionContext.setContext(invocation.getInvocationContext());

        String retCode = null;

        String profileKey = "execute: ";
        try {
        	UtilTimerStack.push(profileKey);
        	
            retCode = invocation.invoke();
        } finally {
            if (cleanupContext) {
                ActionContext.setContext(nestedContext);
            }
            UtilTimerStack.pop(profileKey);
        }

        return retCode;
    }

 

 

 DefaultActionInvocation 得 invoke 方法。

 

 public String invoke() throws Exception {
    	String profileKey = "invoke: ";
    	try {
    		UtilTimerStack.push(profileKey);
    		
    		if (executed) {
    			throw new IllegalStateException("Action has already executed");
    		}

    		if (interceptors.hasNext()) {
    			final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
    			UtilTimerStack.profile("interceptor: "+interceptor.getName(), 
    					new UtilTimerStack.ProfilingBlock<String>() {
							public String doProfiling() throws Exception {
				    			resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
				    			return null;
							}
    			});
    		} else {
    			resultCode = invokeActionOnly();
    		}

    		// this is needed because the result will be executed, then control will return to the Interceptor, which will
    		// return above and flow through again
    		if (!executed) {
    			if (preResultListeners != null) {
    				for (Iterator iterator = preResultListeners.iterator();
    					iterator.hasNext();) {
    					PreResultListener listener = (PreResultListener) iterator.next();
    					
    					String _profileKey="preResultListener: ";
    					try {
    						UtilTimerStack.push(_profileKey);
    						listener.beforeResult(this, resultCode);
    					}
    					finally {
    						UtilTimerStack.pop(_profileKey);
    					}
    				}
    			}

    			// now execute the result, if we're supposed to
    			if (proxy.getExecuteResult()) {
    				executeResult();
    			}

    			executed = true;
    		}

    		return resultCode;
    	}
    	finally {
    		UtilTimerStack.pop(profileKey);
    	}
    }

 

resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
是判断这个action是否有未被执行的拦截器,

 

resultCode = invokeActionOnly();

如没有或拦截器执行完毕,则执行invokeActionOnly

 

 invokeActionOnly方法

 

    public String invokeActionOnly() throws Exception {
    	return invokeAction(getAction(), proxy.getConfig());
    }

   protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
        String methodName = proxy.getMethod();

        if (LOG.isDebugEnabled()) {
            LOG.debug("Executing action method = " + actionConfig.getMethodName());
        }

        String timerKey = "invokeAction: "+proxy.getActionName();
        try {
            UtilTimerStack.push(timerKey);
            
            boolean methodCalled = false;
            Object methodResult = null;
            Method method = null;
            try {
                method = getAction().getClass().getMethod(methodName, new Class[0]);
            } catch (NoSuchMethodException e) {
                // hmm -- OK, try doXxx instead
                try {
                    String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
                    method = getAction().getClass().getMethod(altMethodName, new Class[0]);
                } catch (NoSuchMethodException e1) {
                	// well, give the unknown handler a shot
                	if (unknownHandler != null) {
	                	try {
	                		methodResult = unknownHandler.handleUnknownActionMethod(action, methodName);
	                		methodCalled = true;
	                	} catch (NoSuchMethodException e2) {
	                		// throw the original one
	                		throw e;
	                	}
                	} else {
	            		throw e;
	            	}
                }
            }
        	
        	if (!methodCalled) {
        		methodResult = method.invoke(action, new Object[0]);
        	}
        	
            if (methodResult instanceof Result) {
            	this.explicitResult = (Result) methodResult;
            	return null;
            } else {
            	return (String) methodResult;
            }
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("The " + methodName + "() is not defined in action " + getAction().getClass() + "");
        } catch (InvocationTargetException e) {
            // We try to return the source exception.
            Throwable t = e.getTargetException();

            if (actionEventListener != null) {
                String result = actionEventListener.handleException(t, getStack());
                if (result != null) {
                    return result;
                }
            }
            if (t instanceof Exception) {
                throw(Exception) t;
            } else {
                throw e;
            }
        } finally {
            UtilTimerStack.pop(timerKey);
        }
    }

 

method = getAction().getClass().getMethod(methodName, new Class[0]);
取出需执行的action的方法,如 execute()

 

methodResult = method.invoke(action, new Object[0]);
利用反射,执行action 方法

 

上边就是利用proxy模式,调用一个action的具体逻辑 的 过程。

 

一般的action里,都有一些变量,如从request中取出的参数等,

如要执行action 方法,如execute(),则必须先吧这些变量赋值 已供方法中使用,

这个工作,就是 拦截器(Interceptor) 的任务之一,

 

下篇探讨一下拦截器。

 

你可能感兴趣的:(工作)