`

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

阅读更多

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);	 
 }

 

 

 

分享到:
评论

相关推荐

    struts 拦截器动态代理

    Struts拦截器是Java Web开发框架Struts2中的核心组件之一,它允许开发者在Action执行前后插入自定义的处理逻辑,实现AOP(面向切面编程)的理念。动态代理则是Java提供的一种机制,允许在运行时创建接口的实现类实例...

    Struts2 拦截器 和 Java 中的动态代理

    这个设计模式与Java动态代理的调用逻辑非常相似。 Struts2通过其内部的动态代理机制,如`DefaultActionInvocation`和`StrutsProxy`类,实现了对Action的拦截。这些类利用了Java的反射API,创建了一个代理对象,该...

    Struts2工作流程

    6. **Action创建与调用**:ActionProxy创建一个`ActionInvocation`实例,`ActionInvocation`使用代理模式调用Action,并在调用前后执行相应的拦截器。 7. **拦截器链**:在调用Action之前和之后,拦截器链会按配置...

    Struts2详细工作流程

    接着,ActionProxy创建一个ActionInvocation实例,ActionInvocation会利用代理模式调用Action,并在调用之前加载所有与Action相关的Interceptor(拦截器)。 拦截器是Struts2的重要特性,它们允许在Action执行前后...

    struts2流程与流程图

     ActionProxy创建一个ActionInvocation实例,同时ActionInvocation通过代理模式调用Action。但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)。  一旦Action执行完毕,...

    SSH集成代理1.2版第一种和struts.xml中DelegatingActionProxy代理搭配

    然后定义通知(advice),如前置通知(before advice)在Action执行前运行,后置通知(after advice)在执行后运行。 4. **整合DelegatingActionProxy**:`DelegatingActionProxy`会在运行时根据`struts.xml`的配置...

    Struts2架构剖析

    ActionContext是每个Action执行的上下文环境,它包含了一组对象,如session、application、parameter等,这些都是Action在执行过程中可能需要的数据。ActionContext为Action提供了访问请求和会话数据的途径。 总的...

    Java Reflection in Action

    在程序分析工具的开发上,反射则可以用来分析类的结构和方法,帮助开发者理解复杂代码的执行流程。 综上所述,Java Reflection in Action不仅为读者提供了一个清晰的关于Java反射机制的全面了解,而且还介绍了如何...

    C#pac设计模式小程序

    在这个模式中,Proxy(代理)负责处理客户端的请求,Actor(执行者)执行实际操作,而Command(命令)封装了具体的业务逻辑。这种模式常用于复杂系统中,以提高代码的可维护性和可扩展性。下面,我们将深入探讨C#中...

    ActionInvocation 源码阅读

    同时,通过对`ActionInvocation`的扩展,还可以实现更复杂的应用场景,如动态改变Action执行路径、在Action执行过程中注入额外的数据等。 总的来说,`ActionInvocation`是Struts2框架中AOP的核心实现,它的源码阅读...

    计算多线程环境下执行任务时间1

    此外,代码中还使用了代理模式,通过创建一个匿名内部类来包装用户提供的`Runnable`任务。这样做允许在执行`action.run()`前后添加额外的逻辑,如记录开始和结束时间,或者处理异常。 测试代码应该包含调用`time()`...

    spring integration in action

    - **企业集成模式:** 引入了企业服务总线(ESB)、适配器、代理模式等概念,以及如何使用这些模式解决实际问题。 - **Spring Integration 如何简化集成开发:** 通过使用标准的 Java POJO 和 Spring Bean 定义,...

    Struts2_Spring mvc执行原理的面试题

    7. **返回结果处理**:Action执行完成后,ActionInvocation根据配置找到对应的返回结果,通常是渲染一个JSP页面或使用其他视图技术。 8. **视图呈现**:返回结果被渲染并呈现给客户端。 ### Spring MVC组件解析 ##...

    struts2入门实例和工作(流程)原理

    6. 在Action执行过程中,可以使用拦截器(Interceptor)进行预处理和后处理,拦截器链可以根据配置动态调整。 7. Action执行完成后,ActionInvocation返回结果,结果可以是跳转到另一个Action,或者渲染一个JSP、...

    Struts1、2的工作原理

    ActionProxy是框架的代理模式实现,负责实际的Action调用。 6. **Configuration Manager**:ActionProxy根据配置管理器(Configuration Manager)读取struts.xml配置文件,找到要执行的Action类。 7. **...

    详细的strut2开发教程

    例如,对于`login.action`,Struts2会调用名为`login`的Action执行。 3. **业务控制器和Action代理** 用户实际实现的业务逻辑并不直接处理请求,而是通过Action代理实现。Action代理(`ActionProxy`)通过`...

    struts2.0拦截器完整

    拦截器(Interceptor)是Struts2.0中的核心组件之一,它允许开发者在Action执行前后插入自定义的逻辑,以实现如日志记录、权限检查、事务管理等通用功能。下面我们将深入探讨Struts2.0拦截器的完整知识体系。 1. **...

    BanyanT-1.6.1调试代理软件

    【BanyanT-1.6.1调试代理软件】是一款专为电子工程师设计的调试工具,主要用于通过JTAG(Joint Test Action Group)接口进行程序的烧录与调试。JTAG是一种国际标准测试协议,最初是为了电路板级的测试而设立,但后来...

    Struts2工作原理

    ActionInvocation控制着Action的执行流程,它持有Action实例以及一系列Interceptor,确保Action能在适当的环境下执行。 #### Interceptor机制与Action执行 ActionInvocation遵循命名模式进行调用,首先根据配置...

Global site tag (gtag.js) - Google Analytics