相关的概念:
ActionProxyFactory: create ActionProxy factory,create ActionInvocation,create ActionProxy ActionProxy: serves as client code‘s handle to execute an action,it holds an ActionInvocation which reprents the current satate of the execution of the action.ActionProxy is created by a ActionProxyFactory in a dispatcher.ActionProxy sets up the execute context for the ActionInvocation and then calls invoke() on the ActionInvocation. ActionInvocation: reprents the current state of the execution of the action,it holds the action instance ,the interceptors to be applied,the map of results,and an ActionContext. ActionContext: which includes the request parameters,the application map ,the session map,the Local, and the ServletRequest and ServletResponse.
执行过程如下: (1)在web.xml中指定的ServletDispacter或者FilterDispatcher,负责调用ActionProxyFactory完成ActionProxy的创建,ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, context); (2)ActionProxy 为ActionInvocation设定执行环境上下文,并调用ActionInvocation的invoke()方法
(3)关键在于ActionInvocation的invoke()方法,
public String invoke() throws Exception { if (executed) { throw new IllegalStateException("Action has already executed"); }
if (interceptors.hasNext()) { // notice here is if ,not while InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); /** 调用拦截器的方法,将ActionInvocation作为参数 * 在intercept(this);中回调invoke() 方法,是一种递归的方式 */ resultCode = interceptor.getInterceptor().intercept(this); } 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(); listener.beforeResult(this, resultCode); } }
// now execute the result, if we‘re supposed to if (proxy.getExecuteResult()) { //执行结果的返回 executeResult(); }
executed = true; }
return resultCode; }
|
public String intercept(ActionInvocation invocation) throws Exception { String result = null;
before(invocation); result = invocation.invoke(); // 回调Invocation 的invoke()方法 after(invocation, result);
return result; }
|
为了看得更加清楚,我简化了上面得代码,如下:
/** * 演示了递归得一个实现方式 */ import java.util.ArrayList; import java.util.Iterator;
public class ActionInvocation { public boolean executed = false;
protected Iterator intercepters;
public String resultCode;
public String invoke() throws Exception { if (executed) { throw new IllegalStateException("Action has already executed"); }
if (intercepters.hasNext()) { Intercepter intercepter = (Intercepter) intercepters.next(); //递归 // here is recure point ,programm run to here // then save the state into the stack ,and jump to the top of the method run again // and so and so util the condition to else branch resultCode = intercepter.intercept(this); } else { resultCode = invokeActionOnly(); }
if (!executed) { System.out.println("now it is time to run the action, and this method should not run again!!"); executed = true; } return resultCode; }
private String invokeActionOnly() { System.out.println("run invokeActionOnly() "); // invoke和intercept的递归的时候返回都将是这个值,所以这个返回值能够保存到最后, // 只是在两个方法之间被多次地传递 return "here is action return value,it‘s the result;"; }
public ActionInvocation(){ ArrayList<Intercepter> ay=new ArrayList<Intercepter>(); ay.add(new Intercepter(1)); ay.add(new Intercepter(2)); ay.add(new Intercepter(3)); intercepters=ay.iterator(); } public static void main(String[] args) { ActionInvocation actionInvocation =new ActionInvocation(); try { System.out.println(actionInvocation.invoke()); } catch (Exception e) { e.printStackTrace(); } }
}
/** * 演示了递归得一个实现方式 */ public class Intercepter { private int id;
public Intercepter(int id){ this.id=id; } public String intercept(ActionInvocation actionInvocation) throws Exception { String result = null; System.out.println("run the intercept()"+this.id); return actionInvocation.invoke(); }
}
|
|