标签:
其中属性模式有:PO(持久化对象)、BO(业务对象)、VO(值对象)、DTO(传输数据对象)、FromBean(页面对象)他们是对JavaBean的扩展增强。行为模式其中的方法是“请求对应模式”的天然载体。
使用保证程序的可读性、可维护性和可扩展性。简单就是美,面向对象编程。降低耦合。
Struts2处理HTTP请求。doFilter方法的运行。
XML文件的配置元素是Properties文件配置元素的超集。
②对象与其关联对象的依赖关系的处理机制。
仅仅爱后的inject调用过程,仅仅只是是调用factory构建对象。并使用Java其中最为普通的反射机制来完毕依赖注入。
<bean name ="entity" type ="com.yang.test.Entity" class ="com.yang.test.Entity" />是通过IOC容器管理得到实例的。依据bean节点中class类型的不同採用不同的InternalFactory的匿名实现,当class中含有@Inject注解时。InternalFactory的create方法调用了Container.inject()方法以实现注入。
ObjectFactory.buildBean()的运行过程分两步。第一步调用Class.netInstance()建立要创建对象的实例,第二部调用Container.inject()实现依赖注入。两者的不同主要体如今实例的创建上,前者是通过在struts.xml其中声明bean节点实现的。而后者无需多余的操作,仅仅要类的构造函数合法就可以。
对于“弱类型”与“强类型”之间的转换匹配在Struts2中由“表达式引擎”完毕。数据訪问(从Controller层流转到View层)的困境,主要还是来源于数据模型在某些层次的表现缺乏足够的表现力。
比如。在View层,即没有数据类型的概念也没有数据结构的概念。
OGNL(Object Graph Navigation Language)。是一种表达式语言。使用这样的表达式语言,你可以通过某种表达式语法,存取Java对象树中的随意属性、调用Java对象树的方法、同一时候可以自己主动实现必要的类型转化。假设我们把表达式看做是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁。
当中使用Map作为数据载体的缺点例如以下:
这三大体有一下关系:调用关系、映衬关系。
我们能够使用一个战斗序列。来对这五大元素之间的关系进行诠释。
每当一个战役打响的时候,总指挥部总是须要分派一个详细番号的部队(ActionProxy)来运行战斗。不论什么一支部队,都有主力军(Action)和策应部队(Interceptor)。
主力军(Action)负责核心战斗,而策应部队(Interceptor)则负责对主力部队进行策应和援助。然而,全部的战斗指令都是由部队的指挥官(ActionInvocation)决定的。指挥官(ActionInvocation)是一个部队(ActionProxy)的核心,他将负责主力部队(Action)和策应部队(Interceptor)的调度。当一个战斗结束以后。指挥官(ActionInvocation)还要负责指挥部队下一步的动向(Result),是乘胜追击敌人。还是继续待命。
ValueStack是ActionContext的一个组成部分。ActionContext是XWork的数据流实现元素,作为一个数据载体,它既负责数据存储,又负责数据共享。ValueStack是一个具备表达式引擎计算能力的数据结构。
XWork将ValueStack置于ActionContext中的目的在于为静态的数据加入动态计算的功能。
在XWork的控制流中,时间处理驱动元素对时间处理结点元素形成调用关系。
当中,Action位于栈底,整个栈中除了Action之外就是Interceptor。
其中ActionContext中的数据存储採用的是获得Request、Session、Application等容器的引用。其存储的对象具有与Web容器无关的特点。其中数据共享,採用的是ThreadLocal的方式实现。这样的实现方式,使得程序可以在线程级别上达到数据的共享。
其中CompoundRootAccessor是这样的操作进行的运行者。就是说。CompoundRootAccessor定义了这样的操作进行的方式,其提供操作(单对象root变为对象栈后对栈进行訪问的操作)的具体实现。
ActionContext的创建总是伴随着ValueStack的创建,ValueStack的上下文环境与ActionContext的数据存储空间是等同的。
对于对应数据,最合适的表达方式是方法的返回值。可是Web框架在响应处理上必须包括响应数据和响应流程控制着两个不同的方面。
单一元素的返回值非常难同一时候表达数据和控制着两个不同的层面。相对于SpringMVC其中使用ModelAndView的方式。Struts2中使用有状态的POJO对象进行请求的对应,在数据訪问上有天然的优势。Struts2中的Action具有属性特征和行为特征,是一个状态和动作的合体。Servlet与Struts2的核心差别在于处理请求的核心处理类是不是一个有状态的对象。
Servlet模式,採用的是參数-參数模式。而Struts2採用的是POJO模式。后者是有状态的,前者是无状态的。
在调度运行时依照栈操作中的”先进后出“的原则。Interceptor依照顺序依次运行,最后才轮到Aciton的运行。
Spring是用IoC来实现AOP,而Struts2採用的是AOP来实现IoC。
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try { prepare.setEncodingAndLocale(request, response); prepare.createActionContext(request, response);//创建ActionContext prepare.assignDispatcherToThread(); if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) { chain.doFilter(request, response); } else { request = prepare.wrapRequest(request); ActionMapping mapping = prepare.findActionMapping(request, response, true); if (mapping == null) { boolean handled = execute.executeStaticResourceRequest(request, response); if (!handled) { chain.doFilter(request, response); } } else { execute.executeAction(request, response, mapping);//运行拦截器-Action } } } finally { prepare.cleanupRequest(request);//清理ActionContext } }
/** * Cleans up a request of thread locals */ public void cleanupRequest(HttpServletRequest request) { Integer counterVal = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER); if (counterVal != null) { counterVal -= 1; request.setAttribute(CLEANUP_RECURSION_COUNTER, counterVal); if (counterVal > 0 ) { if (log.isDebugEnabled()) { log.debug("skipping cleanup counter="+counterVal); } return; } } // always clean up the thread request, even if an action hasn‘t been executed ActionContext.setContext(null); Dispatcher.setInstance(null); }
ActionContext是控制流元素与数据流元的够沟桥梁。
设置引用的过程在DefaultActionInvocation的init方法其中,这种方法的引用序列为DefaultActionInvocation.init()→DefaultActionProxy.prepare()→DefaultActionProxyFactory.createActionProxy()→
Dispatcher.serviceAction()→ExecuteOperations.executeAction()→StrutsPrepareAndExecuteFilter.doFilter()
if (pushAction) { stack.push(action); contextMap.put("action", action); }
算法——环绕着核心配置元素的初始化过程。Struts2初始化主线的核心驱动力,正是对各种配置形式所进行的一次统一的对象化处理。Struts2在初始化的时候,将各种各样的配置元素,不管是XML形式还是Properties文件形式(设置有可能是其它自己定义的配置形式)转化为Struts2多定义的Java对象或者Struts2执行时的參数的处理过程。Struts2在初始化过程其中的额外辅助对象有三类:①配置元素载入器(将配置文件——>框架元素)②配置元素构造器(框架元素的初始化)③配置元素管理类(对配置元素的数据存储和配置元素的初始化行为进行控制)。
Struts2的初始化对象分为两类。一类是容器对象。另外一类是事件映射对象。
/** * Load configurations, including both XML and zero-configuration strategies, * and update optional settings, including whether to reload configurations and resource files. */ public void init() { //初始化configurationManager if (configurationManager == null) { configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME); } try { init_DefaultProperties(); // [1] DefaultPropertiesProvider继承至LegacyPropertiesConfigurationProvider /org/apache/struts2/default.properties 文件载入器 init_TraditionalXmlConfigurations(); // [2] StrutsXmlConfigurationProvider struts-default.xml,struts-plugin.xml XmlConfigurationProvider struts.xml init_LegacyStrutsProperties(); // [3] LegacyPropertiesConfigurationProvider 载入除default.properties之外的strutus相关的properties文件 //[4]init_PreloadConfiguration() init_CustomConfigurationProviders(); // [5] 用户自己定义配置载入类 初始化用户自己定义的配置载入器(这个载入器通过Filter的初始化參数配置) init_FilterInitParameters() ; // [6] ConfigurationProvider匿名内部类实现 载入Filter的初始化配置信息将定义的initParams从web.xml中读入,放入props init_AliasStandardObjects() ; // [7] BeanSelectionProvider 依据struts常量配置 初始化与其它框架整合用到的类,比如xml中配置struts.objectFactory为spring就须要StrutsSpringObjectFactory //init_PreloadConfiguration会调用ConfigurationManager.getConfiguration()会调用 DefaultConfiguration.reloadContainer()在这里面会循环调用上面七个ConfigurationProvider的register方法 Container container = init_PreloadConfiguration(); //[4] 创建容器,对容器进行依赖注入 平对package进行注入 container.inject(this);//额外的初始化操作,检查是否支持reloading载入和对weblogicserver的特殊设置。init_CheckConfigurationReloading(container); init_CheckWebLogicWorkaround(container); if (!dispatcherListeners.isEmpty()) { for (DispatcherListener l : dispatcherListeners) { l.dispatcherInitialized(this); } } } catch (Exception ex) { if (LOG.isErrorEnabled()) LOG.error("Dispatcher initialization failed", ex); throw new StrutsException(ex); } }
createContextMap(Map, Map, Map, Map, HttpServletRequest, HttpServletResponse, ServletContext) createContextMap(HttpServletRequest, HttpServletResponse, ActionMapping, ServletContext) wrapRequest(HttpServletRequest, ServletContext) prepare(HttpServletRequest request, HttpServletResponse response)
serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping)
void cleanup()
Dispatcher是Struts2与Xwork的分界点。也是将MVC实现与Web容器相隔离的分界点。
public interface ConfigurationProvider extends ContainerProvider, PackageProvider { }
public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException;表示在Container容器中注冊bean和properties(注冊工作由ContainerBuilder完毕?)。不同的ContainerProvider之间没有依赖关系。因此这是框架提供的隐含扩展点,仅仅要新类型实现了ContainerProvider接口,就能实现实现自己定义配置表现形式。并将其载入到容器其中。
public void loadPackages() throws ConfigurationException;载入全部的Package定义,并创建PackageConfig对象。其中XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider实现了这种方法,创建了PackageConfig对象。PackageConfig对象与xml配置文件其中package结点相相应。
主要进行參数搜索和创建对象操作。
当中BeanSelectionProvider和XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider在register方法中使用了改构造器。本构造器主要用于将配置表中的结点注冊到Container当中。
初始化驱动元素。ConfigurationManager是整个配置元素进行操作的代理接口类,而真正对全部配置元素的初始化进行调度的是Configuration对象。
是配置元素的操作接口。
其在Dispatcher初始化和结束时会被调用。
还能够通过继承StrutsPrepareAndExecuteFilter并重写protected voidpostInit(Dispatcher dispatcher, FilterConfig filterConfig) { } 完毕初始化时的扩展工作。
由于extraContext的创建过程使用了函数Dispatcher.createContextMap(),与ActionContext和ValueStack创建的过程是一样的(调用了同一个函数),也就是说。extraContext的与ActionContext和ValueStack的上下文环境是等同的。
同一时候还有关键的一步就是将拦截器栈的迭代器指针重置到了栈顶位置。
JSP。Java Server Page同意在构成Page的HTML语言之上嵌入Java的语法片段,从而加强其余Server的交互能力。
JSP的引入攻克了两个方面的问题。
核心程序:①抽取各个功能模块的公共逻辑成为一个独立的核心功能模块。②为核心功能模块加入对其它功能模块的运行调度功能。不同功能模块之间没有依赖关系,插件模块与主模块之间存在调用关系。这是一种星形依赖关系。
客户功能模块对插件模块进行调度,不同插件模块之间没有依赖关系,功能模块之间保持独立。不会互相影响。如Chrome的插件,和Eclipse的插件OSGi。
Struts2的插件只对Struts2的核心Jar构成依赖关系,不同插件之间原则上不存在依赖关系。由于没有依赖关系,因此插件的载入顺序是随机的。
标签:
原文地址:http://www.cnblogs.com/yxwkf/p/5134314.html