您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 工程监理 > struts2代码分析
1.Struts2架构图和请求处理流程请求首先通过Filterchain,Filter主要包括ActionContextCleanUp,它主要清理当前线程的ActionContext和Dispatcher;FilterDispatcher主要通过AcionMapper来决定需要调用哪个Action。ActionMapper取得了ActionMapping后,在Dispatcher的serviceAction方法里创建ActionProxy,ActionProxy创建ActionInvocation,然后ActionInvocation调用Interceptors,执行Action本身,创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。2.Struts2部分类介绍这部分从Struts2参考文档中翻译就可以了。ActionMapperActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了Action对于Request等javaServlet类的依赖。Struts2中它的默认实现类是DefaultActionMapper,ActionMapper很大的用处可以根据自己的需要来设计url格式,它自己也有Restful的实现,具体可以参考文档的docs¥actionmapper.html。ActionProxy&ActionInvocationAction的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默认实现DefaultActionProxy是由ActionInvocation持有Action实例。ActionProxy作用是如何取得Action,无论是本地还是远程。而ActionInvocation的作用是如何执行Action,拦截器的功能就是在ActionInvocation中实现的。ConfigurationProvider&ConfigurationConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主要是尤其实现类XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider来解析。3.Struts2请求流程1、客户端发送请求2、请求先通过ActionContextCleanUp--FilterDispatcher3、FilterDispatcher通过ActionMapper来决定这个Request需要调用哪个Action4、如果ActionMapper决定调用某个Action,FilterDispatcher把请求的处理交给ActionProxy,这儿已经转到它的Delegate--Dispatcher来执行5、ActionProxy根据ActionMapping和ConfigurationManager找到需要调用的Action类6、ActionProxy创建一个ActionInvocation的实例7、ActionInvocation调用真正的Action,当然这涉及到相关拦截器的调用8、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。添加PreResultListener可以在Interceptor中实现。首先强调一下struts2的线程程安全,在Struts2中大量采用ThreadLocal线程局部变量的方法来保证线程的安全,像Dispatcher等都是通过ThreadLocal来保存变量值,使得每个线程都有自己独立的实例变量,互不相干.接下来就从Dispatcher开始看起,先看其构造函数://创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方publicDispatcher(ServletContextservletContext,MapString,StringinitParams){this.servletContext=servletContext;//配置在web.xml中的param参数this.initParams=initParams;}//创建Dispatcher,此类是一个Delegate,它是真正完成根据url解析转向,读取对应Action的地方publicDispatcher(ServletContextservletContext,MapString,StringinitParams){this.servletContext=servletContext;//配置在web.xml中的param参数this.initParams=initParams;}我们再看在FilterDispatcher创建Dispatcher的:protectedDispatchercreateDispatcher(FilterConfigfilterConfig){MapString,Stringparams=newHashMapString,String();for(Enumeratione=filterConfig.getInitParameterNames();e.hasMoreElements();){Stringname=(String)e.nextElement();Stringvalue=filterConfig.getInitParameter(name);params.put(name,value);}都可以从FilterConfig中得到returnnewDispatcher(filterConfig.getServletContext(),params);}protectedDispatchercreateDispatcher(FilterConfigfilterConfig){MapString,Stringparams=newHashMapString,String();for(Enumeratione=filterConfig.getInitParameterNames();e.hasMoreElements();){Stringname=(String)e.nextElement();Stringvalue=filterConfig.getInitParameter(name);params.put(name,value);}都可以从FilterConfig中得到returnnewDispatcher(filterConfig.getServletContext(),params);}分七步载入各种配置属性,都是通过ConfigurationProvider接口进行的,这个接口提供init(),destroy(),register()等方法.将各种ConfigurationProvider初始化之后将实例添加到ConfigurationManager的List里面.最后通过循环调用List里的这些destroy(),register()等方法实现对配置文件的属性进行注册和销毁等功能.下面将分析这七层功夫是怎样一步步练成的.首先是init_DefaultProperties()创建Dispatcher之后,来看init()方法init()方法是用来Load用户配置文件,资源文件以及默认的配置文件.主要分七步走,看下面注释publicvoidinit(){if(configurationManager==null){//设置ConfigurationManager的defaultFrameworkBeanName.//这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等configurationManager=newConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);}//读取properties信息,默认的default.properties,init_DefaultProperties();//[1]//读取xml配置文件init_TraditionalXmlConfigurations();//[2]//读取用户自定义的struts.propertiesinit_LegacyStrutsProperties();//[3]//自定义的configProvidersinit_CustomConfigurationProviders();//[5]//载入FilterDispatcher传进来的initParamsinit_FilterInitParameters();//[6]//将配置文件中的bean与具体的类映射init_AliasStandardObjects();//[7]//构建一个用于依赖注射的Container对象//在这里面会循环调用上面七个ConfigurationProvider的register方法//其中的重点就是DefaultConfiguration的#reload()方法Containercontainer=init_PreloadConfiguration();container.inject(this);init_CheckConfigurationReloading(container);init_CheckWebLogicWorkaround(container);if(!dispatcherListeners.isEmpty()){for(DispatcherListenerl:dispatcherListeners){l.dispatcherInitialized(this);}}}publicvoidinit(){if(configurationManager==null){//设置ConfigurationManager的defaultFrameworkBeanName.//这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等configurationManager=newConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);}//读取properties信息,默认的default.properties,init_DefaultProperties();//[1]//读取xml配置文件init_TraditionalXmlConfigurations();//[2]//读取用户自定义的struts.propertiesinit_LegacyStrutsProperties();//[3]//自定义的configProvidersinit_CustomConfigurationProviders();//[5]//载入FilterDispatcher传进来的initParamsinit_FilterInitParameters();//[6]//将配置文件中的bean与具体的类映射init_AliasStandardObjects();//[7]//构建一个用于依赖注射的Container对象//在这里面会循环调用上面七个ConfigurationProvider的register方法//其中的重点就是DefaultConfiguration的#reload()方法Containercontainer=init_PreloadConfiguration();container.inject(this);init_CheckConfigurationReloa
本文标题:struts2代码分析
链接地址:https://www.777doc.com/doc-4524564 .html