以动态代理模式看Action的执行流程

本文深入解析了Struts框架中Action的动态代理执行流程,包括Action、ActionSupport、ActionProxy和ActionInvocation的角色及其作用。以JSP页面提交为例,详细展示了从请求包装到Action执行的整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

action的整个执行流程使用的就是动态代理模式。关于动态代理模式的原理可以看这篇文章:

http://tiro-li.iteye.com/blog/1901678

 

Action:真实角色,这是动态改变的;

ActionSupport:抽象角色,Action实现的接口;

ActionProxy:动态代理角色。相当于Proxy动态生成的$Proxy0类,有以下三点信息需要我们明确。

(1).它在Dispatcher的executeAction方法中由ActionProxyFactory类创建;

(2).通过持有ConfigurationManager的引用获取到Action中要执行的方法(默认为execute),这相当于间接实现了ActionSupport接口;

(3).同时它持ActionInvocation的引用,把Action的执行委托给ActionInvocation处理;

ActionInvocation:相当于在动态代理模型中InvocationHandler的实现类,持有Action的引用,通过反射调用Action的执行方法。

 

以JSP页面提交login.action为例。下面为一个精略的代码流程。其中,ActionMapping为action的映射,用来保存actionName、namespace、method、result等信息。

 

//PrepareOperations是执行前准备的所有操作的包装类
PrepareOperations prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
//ExecuteOperations是执行Action过程所有操作的包装类
ExecuteOperations execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);

//包装request为StrutsRequestWrapper对象
request = prepare.wrapRequest(request);

//创建ActionMapping对象
ActionMapping mapping = prepare.findActionMapping(request, response, true);*
/*
	ActonMapping
	{
		name = "login",
		extension = "action",
		namespace = "/",
		result = "null",
		method = "null";
	}
	
*/

//执行Action
execute.executeAction(request, response, mapping);

//在executeAction中调用Dispatcher的serviceAction方法
public void executeAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException 
{
		dispatcher.serviceAction(request, response, servletContext, mapping);
}

//在Dispatcher的serviceAction方法创建ActionProxy对象
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,ActionMapping mapping) throws ServletException 
{
	Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
	String namespace = mapping.getNamespace();    // "/"
	String name = mapping.getName();			  // "login"
	String method = mapping.getMethod();		  // "null"
	
	//获取得配置文件的Configuration对象
	Configuration config = configurationManager.getConfiguration();
	
	//利用ActionProxy的工厂类ActionProxyFactory创建StrutsActionProxy对象
	 ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
                    namespace, name, method, extraContext, true, false);
	/*
	ActionProxy
	{
		actionName = "login",
		method = "execute",					//由configurationManager解析配置文件获取
		invocation = DefaultActionInvocation
		{
			Action:LoginAction,				//由configurationManager解析配置文件获取
			interceptors:Iterator<InterceptorMapping>   //defaultStack中Interceptor 
		});
	}	
	*/
	
	proxy.execute();
}

//在ActionProxy的execute方法调用invocation的invoke方法
 public String execute() throws Exception 
 {
	return invocation.invoke();
}

//ActionInvocation的invoke方法
public String invoke() throws Exception 
{
	//循环应用defaultStack中的拦截器
	if (interceptors.hasNext()) 
	{
		final InterceptorMapping interceptor = interceptors.next();
		resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
	} 
	else 
	{       
		//Invokes only the Action (not Interceptors or Results),result the resultCode.
		resultCode = invokeActionOnly();            
	}
}

//ActionInvocation的invokeActionOnly方法
public String invokeActionOnly() throws Exception 
{	   
       return invokeAction(getAction(), proxy.getConfig());
    }
}

//ActionInvocation的 invokeAction方法
 protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception 
 {
	 String methodName = proxy.getMethod();
	 //使用反射调用execute方法
	 Method method = getAction().getClass().getMethod(altMethodName, new class[]{});
	 String methodResult = method.invoke(action, new Object[]{}); 

	return saveResult(actionConfig, methodResult);	 
 }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值