`
gutou9
  • 浏览: 145441 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Xwork2 源码阅读(四)

AOP 
阅读更多

xwork2 的Inteceptor,是实现AOP的,我理解的Aop,就是把代码拆开,分成一块一块的。

然后在根据需要组装起来, 而Interceptor 就是代码分块后的一块。 

 

我们看一下xwork的具体实现步骤,

 

1 先是在xwork 配置文件中,配置action有哪些Interceptor ,

2 然后在xwork 初始化的时候,把action 的Interceptor 记录下来,

 

public class ActionConfig extends Located implements Serializable {

    public static final String WILDCARD = "*";

    protected List<InterceptorMapping> interceptors;
    protected Map<String, String> params;
    protected Map<String, ResultConfig> results;
    protected List<ExceptionMappingConfig> exceptionMappings;
    protected String className;
    protected String methodName;
    protected String packageName;
    protected String name;
    protected Set<String> allowedMethods;

 

 interceptors这个参数,记录的就是action配置的interceptor,

3  执行action的主体逻辑之前,先把interceptors 取出来,顺次执行一遍。

 

看一下xwork 是如何实现的,

主要是这三各类 :

DefaultActionInvocation, Action, Interceptor

Action 是我们自己写的,里边有我们要执行的主体逻辑,

Interceptor 则是主体逻辑之外的代码块,如打日志,

 

DefaultActionInvocation 则居中调度,

Action 在他里边,interceptor 由他通过ActionConfig 找到,

这样他就可以把Action和多个Interceptor粘合起来,

 

先看下 DefaultActionInvocation

 

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

这个主干方法,

先判断是否有 interceptor,

      if (interceptors.hasNext()) {


如有,则执行interceptor

    resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this );

 

调用方法时,参数是 DefaultActionInvocation.this,

说明DefaultActionInvocation把自己本身做参数 传给了interceptor,

然后interceptor就有了DefaultActionInvocation的引用,就可以方便的和DefaultActionInvocation进行互通了。

 

看一个具体的 Interceptor,

    public String doIntercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();
        if (!(action instanceof NoParameters)) {
            ActionContext ac = invocation.getInvocationContext();
            final Map parameters = retrieveParametersFromContext(ac);

            if (LOG.isDebugEnabled()) {
                LOG.debug("Setting params " + getParameterLogMap(parameters));
            }
            if (parameters != null) {
            	Map contextMap = ac.getContextMap();
                try {
                	ReflectionContextState.setCreatingNullObjects(contextMap, true);
                	ReflectionContextState.setDenyMethodExecution(contextMap, true);
                	ReflectionContextState.setReportingConversionErrors(contextMap, true);

                    ValueStack stack = ac.getValueStack();
                    setParameters(action, stack, parameters);
                } finally {
                	ReflectionContextState.setCreatingNullObjects(contextMap, false);
                	ReflectionContextState.setDenyMethodExecution(contextMap, false);
                	ReflectionContextState.setReportingConversionErrors(contextMap, false);
                }
            }
        }
        return invocation.invoke();
    }

 具体执行逻辑不用看,只看第一句和最后一句,

Object action = invocation.getAction();

找到action,

return invocation.invoke();
Interceptor执行完本身的逻辑,就把程序的执行权还给ActionInvocation,

而后回到ActionInvocation 的invoke() 方法,

判断是否有后续的Interceptor,重复上述过程,

直到action的所有Interceptor都执行完。

 

当action的所有Interceptor都执行完,就到了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的主体方法,

 methodResult = method.invoke(action, new Object[0]);

执行方法,返回methodResult ,

 

到了这,一个action的Interceptor,已及主体逻辑,就基本执行完了。

 

 

 

 

 

 

 

 

 

 

 

2
0
分享到:
评论

相关推荐

    Xwork2 源码阅读(一)

    《Xwork2 源码阅读(一)——深度解析框架基础与核心机制》 Xwork2是Struts2框架的核心部分,它提供了一种基于Action的模型-视图-控制器(MVC)架构,是Java Web开发中的重要组件。这篇分析文章将深入探讨Xwork2的...

    Xwork2 源码阅读.pdf(附源码)

    《Xwork2 源码阅读.pdf》是一个深入解析Xwork2框架的文档,结合了Webwork和Struts2的源码分析,旨在帮助开发者理解这两个著名MVC框架的内部工作机制。Xwork2是Struts2的核心部分,负责处理Action的执行流程、拦截器...

    xwork2.1.2源码与xwork2.2.1源码

    《深入解析xwork 2.x源码:从2.1.2到2.2.1的演进》 xwork作为一个强大的Action框架,是Struts2的...通过深入学习xwork源码,开发者可以更好地掌握MVC设计模式,理解Web应用的控制层实现,从而在实践中发挥更大的效能。

    xwork2.1.6源码及其之前版本的源码

    8. **设计模式**:XWork源码中运用了多种设计模式,如工厂模式(Factory)、单例模式(Singleton)、装饰器模式(Decorator)等,这些都是Java开发中的经典模式,值得深入研究。 通过学习和分析XWork 2.1.6的源码,...

    struts2 xwork2 源码

    在06170300180这个文件中,可能包含了Struts2和XWork2的源码,你可以通过阅读这些源码来进一步了解这两个框架的实现细节。这将是一个宝贵的资源,帮助你深入学习和掌握Struts2和XWork2,从而提升你的Java Web开发...

    xwork官网源码 下载 xwork

    《深入理解XWork框架:官方源码解析》 XWork是一个强大的Action框架,它为Java Web应用程序提供了模型-视图-控制器(MVC)模式的支持。这个框架的主要目标是简化企业级应用的开发,提高代码的可维护性和可扩展性。...

    xwork_struts2 源码

    这次我们讨论的是"xwork_struts2"源码,包括"struts2-core-2.3.1.2.jar"和"xwork-core-2.3.1.2.jar"两个部分。 1. **XWork核心**:XWork是Struts2的基础,它提供了一套动作框架,负责处理HTTP请求、执行业务逻辑...

    struts2下的xwork源码

    深入学习XWork源码,你可以了解到以下核心部分: 1. **ActionInvocation**:这是执行Action的入口点,它维护了拦截器栈,并负责调用每个拦截器和Action。 2. **ActionProxy**:ActionProxy是ActionInvocation的...

    xwork源码 xwork src Eclipse关联xwork源码

    深入理解XWork源码对于学习和优化Struts2应用至关重要。在这个压缩包中,包含的是XWork 2.0.7版本的源代码,特别适合开发者进行研究和调试。以下是关于XWork源码及如何在Eclipse中关联XWork源码的详细讲解。 1. **...

    xwork源码及札包

    总之,这个"XWork源码及打包"资源包为深入学习和开发基于Struts2的Web应用提供了宝贵的材料,无论是初学者还是经验丰富的开发者,都能从中受益。通过研究源码,开发者不仅可以提高技能,还能更好地利用和定制这个...

    XWork源码+docs全

    XWork是Struts2框架的核心组件,它提供了一种基于拦截器(Interceptor)的Action管理机制,为构建可维护、可扩展的企业级Web应用程序...深入学习XWork源码,对于提升对Struts2乃至整个MVC框架的理解都是非常有益的。

    struts-xwork-core源码

    Struts-xwork-core是Struts2框架的核心组件,它提供了Action和结果的执行模型,以及类型...总之,深入学习Struts-xwork-core的源码,将帮助你更好地掌握Struts2框架的精髓,提高开发效率,解决实际项目中遇到的问题。

    Struts2中xwork源码

    本文将深入探讨XWork的源码,解析其设计理念和关键实现,帮助开发者更好地理解和使用Struts2。 1. **ActionInvocation**:XWork的核心是ActionInvocation,它是执行动作的实际载体。ActionInvocation维护了动作执行...

    XWork 源码

    深入学习XWork源码,我们可以关注以下几个核心概念: - **Action接口与ActionSupport类**:Action接口定义了动作的基本行为,而ActionSupport是它的默认实现,提供了默认的错误处理和结果返回机制。 - **...

    struts2.014和xwork2.07源码下载

    通过阅读源码,我们可以学习到如何设计可扩展的框架,以及如何利用拦截器实现AOP。此外,对于性能优化和问题排查,熟悉源码也具有极大的帮助。 总之,Struts2和XWork是Java Web开发中的重要工具,它们提供了强大的...

    Xwork的源码

    **Xwork源码详解** Xwork是Struts2框架的核心组成部分,主要负责处理Action的业务逻辑,它是表现层框架Struts2的内核。在深入理解Struts2的工作原理时,解析Xwork的源码至关重要。Xwork为Struts2提供了强大的命令...

    xwork-2.0.4源码

    这个源码包是理解Struts2工作原理的关键,因为它包含了xwork的核心实现,包括动作调度、依赖注入、类型转换、拦截器机制等多个关键模块。现在,让我们一起深入探讨xwork-2.0.4源码中的核心知识点。 1. **动作调度...

    xwork的源码jar包

    xwork 2.8的源码,最新版本欢迎下载!

    struts2中xwork源码

    通过对XWork源码的学习,开发者可以深入理解Struts2框架的内部运作机制,包括Action的生命周期、拦截器的执行顺序、OGNL的表达式解析等。这不仅有助于调试和优化代码,也能为自定义扩展或开发更复杂的web应用提供...

    xwork2.0.3 源码

    在XWork源码中,我们可以看到OGNL的解析和表达式求值过程,这对于理解Struts2中的数据绑定至关重要。 5. **TypeConverter**:XWork提供了一套强大的类型转换机制,使得不同类型的参数能够被自动转换成动作方法所需...

Global site tag (gtag.js) - Google Analytics