struts2总结:草稿
2015-12-24 10:28
211 查看
Struts2部分
1,说明整个Struts2的流程,越详细越好(10分)
初始化:
struts2是由过滤器驱动的:核心过滤器StrutsPrepareAndExecuteFilter在web应用启动的时候被服务器创建,并驻留服务器内存;
并调用init方法进行初始化;
过程包括:
a 其中对核心分发器 Dispatcher dispatcher
=
init.initDispatcher(config);进行初始化,核心分发器Dispatcher在被创建的过程中
需要接收两个参数;new
Dispatcher(filterConfig.getServletContext(),
params);即对核心过滤器配置的初始化参数和
配置文件的加载顺序;private static final String
DEFAULT_CONFIGURATION_PATHS =
"struts-default.xml,struts-plugin.xml,struts.xml";
struts.xml配置文件解析器:XmlConfigurationProvider---
静态注入:将struts框架工作所需的对象,包括:
;通过如下方法进行注值;
org.apache.struts2.config.BeanSelectionProvider.register(ContainerBuilder,
LocatableProperties);
需要注入的是,这些值的注入都有一个特点:比如;
<bean
type="com.opensymphony.xwork2.ActionProxyFactory"
name="xwork"
class="com.opensymphony.xwork2.DefaultActionProxyFactory"/>
<bean
type="com.opensymphony.xwork2.ActionProxyFactory"
name="struts"
class="org.apache.struts2.impl.StrutsActionProxyFactory"/>
都有一个公共的接口:com.opensymphony.xwork2.ActionProxyFactory,并针对该接口有多个实现;struts内部肯定是通过接口
引用调用实现类的方法,这又是面向接口编程,大大提高了程序的扩展性;如果你要改写这些配置,
只要在你的struts.xml配置文件中进行配置,但是前提有一个你必须实现它的接口,并将type定义为该接口,将你的实现类
定义为class,并取和上面相同的名称,达到覆盖的效果;
struts2拦截器的创建机制:只有使用到的拦截器才会被创建,这个很好理解,是为了内存消耗的考虑,你没事叫人过来干嘛,
叫过来,又叫人回去,啥事也不干,你不是有病吗?
1
还是由struts2的核心配置文件解析器XmlConfigurationProvider进行解析;
将解析到的一个个interceptor-ref节点封装成InterceptorMapping,多个InterceptorMapping组成一个集合
List<InterceptorMapping>
interceptors;多个集合构成一个
InterceptorStackConfig拦截器栈映射对象;
然后交给ObjectFactory统一创建,具体的是由StrutsObjectFactory进行创建;
protected void loadInterceptorStacks(Element element,
PackageConfig.Builder context) throws ConfigurationException
{
//这句代码的意思是,看看配置文件中哪些拦截器栈被引用了,引用了,就进一步的
//追踪拦截器栈中的拦截器
NodeList
interceptorStackList =
element.getElementsByTagName_r("interceptor-stack");
for (int i = 0; i <
interceptorStackList.getLength(); i++) {
Element interceptorStackElement = (Element)
interceptorStackList.item(i);
InterceptorStackConfig config =
loadInterceptorStack(interceptorStackElement, context);
context.addInterceptorStackConfig(config);
}
}
这最后所有的对象都会跑到ContainerImpl这个容器中,这是struts2的核心容器;即IOC容器;
配置文件默认解析顺序为
default.properties(struts默认的常量信息)--->struts-default.xml--->struts-plugin.xml--->struts.xml;
如果其中有相同信息则后者覆盖前者,因此我们要覆盖struts默认的常量最好是放在struts.xml中的constant元素中;
当然一些插件为了覆盖struts的默认常量也会在对应的struts-plugin.xml中定义常量;并最终汇总到struts.xml中;
总结:核心过滤器的init方法主要做的事:
1 初始化配置文件;
2 初始化核心分发器:Dispatcher
3 初始化PrepareOperations:
他的作用
a:
准备struts的执行环境,具体来说就是创建ActionContext;
b:对request进行包装;
c:action路径的寻址和过滤;
4 初始化ExecuteOperations
他的作用:
a:执行静态资源请求;
b:执行action;
拦截器:只有在action中引用到了,才会在应用加载时创建;
即某个拦截器类出现在interceptor-ref中,才会在初始化的时候被创建;
核心过滤器的init方法的作用;
1
加载并解析配置文件,解析顺序为struts-default.xml,struts-plugin.xml,struts.xml;
如果这三个文件中有相同内容,则后者覆盖前者;配置文件加载后创建struts基本元素:即<bean
type=*,class=*>
结果集合拦截器(只有被引用到的拦截器才会被创建,即interceptor-ref的)
需要注意的是<bean>节点对应的元素,type和class的关系,type:
是父类或者接口,而class是对应的实现类,我们说过配置文件是有加载顺序的,我们要覆盖struts的默认配置
可以在struts.xml,但是覆盖有一个前提,你的实现类,type必须和默认中的type相同;
实现类自己定义,因为在struts调用你的实现类是通过type对应的引用来调用的,实际上的实现类是由你提供的'
这是完全的面向接口(父类)编程,符合开闭原则;比如说
<bean
type="com.opensymphony.xwork2.ObjectFactory" name="struts"
class="org.apache.struts2.impl.StrutsObjectFactory"
/>这是struts中的默认配置,你要修改他的创建模式;
就必须和他继承相同的父类;比如spring集成struts的插件中的struts-plugin.xml配置文件的配置;
<bean type="com.opensymphony.xwork2.ObjectFactory"
name="spring"
class="org.apache.struts2.spring.StrutsSpringObjectFactory"
/>
在struts中一定有这么一行代码:
ObjectFactory objectFactory;并提供相应的set,get方法
然后在使用到的地方直接就是
objectFactory.buildBean();//至于这个buildBean怎么执行不管,但是你的实现类一定要有这个方法;
否则就会导致整个框架的混乱
开闭原则:
实现类你爱怎么实现怎么实现,这是开的一方面;
但是你必须得保证,我父类有的方法一定要有实现;
或者说我的buildBean一定要能执行;这是闭的一方面;
同时配置文件中的内容允许覆盖也正是体现了这点,如果你都不允许他人覆盖你的配置,把什么都写死了,三大框架整合就是
个笑话.
一句话:开闭原则就是对于扩展性我完全开放,但是对于我struts整个的执行流程,谁都不能动,这是我的根基;
2
当请求到来的时候,首先经过核心过滤器的doFilter方法;这个方法实现了以下功能;
a:初始化action执行环境,ActionContext;
对请求url进行解析,并判断你的url是否是需要经过struts的核心;
如果需要做进一步的处理,如果不需要执行chain.doFilter放行;
当然这一步是粗粒度的进行判断,接下来对请求进行包装,解析出对应的action;
并在ActionMapping中找看是否存在对应的action映射;
如果不存在,继续判断是否是要使用到struts的静态资源,即路径中有
"/struts/":对应于org.apache.struts2.template中的静态资源;
"/static/"对应于org.apache.struts2下的static包中的静态资源;
如果有调用静态资源处理器进行处理,如果没有直接放行;
如果
actionMapping中有对应的action;
执行execute.executeAction(request, response,
mapping);方法,进入struts的核心
调用核心分发器的serviceAction方法创建值栈对象ValueStack和contextMap;
并创建出ActionProxy,由ActionProxy创建出ActionInvocation,即核心控制单元,他采用的是command设计模式进行设计;;
由ActionInvocation控制拦截器和action,
和result的执行;
在执行proxy.invoke方法就回到ActionInvocation,由ActionInvocation
负责拦截器的执行,拦截器执行完成后,执行目标action的目标方法,
并返回一个路由串,即结果视图,然后又回到ActionInvocation,继续执行Result中的代码,
result根据配置文件中配置的结果视图类型和页面跳转地址,
这时候通常还得调用jsp等模板对结果进行处理,---是否使用到标签用OGNL解析器进行处理,
形成最终的数据;
然后重新回到ActionInvocation,继续调用
拦截器的清理工作,拦截器都执行完成后,
响应消息写入到response缓冲区,由服务器取出,
以http响应格式输出到浏览器供浏览器解析,
核心过滤器的doFilter方法执行结束,
本次请求结束;ActionContext中的数据被清空;
我们发现核心过滤器和其他过滤器共同构成一个职责链设计模式,整个职责链由tomcat服务器进行控制;
每个过滤器完成自己的功能:1要么直接返回数据到页面
2要么执行完自己的功能后通知下一个过滤器执行;
1,说明整个Struts2的流程,越详细越好(10分)
初始化:
struts2是由过滤器驱动的:核心过滤器StrutsPrepareAndExecuteFilter在web应用启动的时候被服务器创建,并驻留服务器内存;
并调用init方法进行初始化;
过程包括:
a 其中对核心分发器 Dispatcher dispatcher
=
init.initDispatcher(config);进行初始化,核心分发器Dispatcher在被创建的过程中
需要接收两个参数;new
Dispatcher(filterConfig.getServletContext(),
params);即对核心过滤器配置的初始化参数和
配置文件的加载顺序;private static final String
DEFAULT_CONFIGURATION_PATHS =
"struts-default.xml,struts-plugin.xml,struts.xml";
struts.xml配置文件解析器:XmlConfigurationProvider---
静态注入:将struts框架工作所需的对象,包括:
;通过如下方法进行注值;
org.apache.struts2.config.BeanSelectionProvider.register(ContainerBuilder,
LocatableProperties);
需要注入的是,这些值的注入都有一个特点:比如;
<bean
type="com.opensymphony.xwork2.ActionProxyFactory"
name="xwork"
class="com.opensymphony.xwork2.DefaultActionProxyFactory"/>
<bean
type="com.opensymphony.xwork2.ActionProxyFactory"
name="struts"
class="org.apache.struts2.impl.StrutsActionProxyFactory"/>
都有一个公共的接口:com.opensymphony.xwork2.ActionProxyFactory,并针对该接口有多个实现;struts内部肯定是通过接口
引用调用实现类的方法,这又是面向接口编程,大大提高了程序的扩展性;如果你要改写这些配置,
只要在你的struts.xml配置文件中进行配置,但是前提有一个你必须实现它的接口,并将type定义为该接口,将你的实现类
定义为class,并取和上面相同的名称,达到覆盖的效果;
struts2拦截器的创建机制:只有使用到的拦截器才会被创建,这个很好理解,是为了内存消耗的考虑,你没事叫人过来干嘛,
叫过来,又叫人回去,啥事也不干,你不是有病吗?
1
还是由struts2的核心配置文件解析器XmlConfigurationProvider进行解析;
将解析到的一个个interceptor-ref节点封装成InterceptorMapping,多个InterceptorMapping组成一个集合
List<InterceptorMapping>
interceptors;多个集合构成一个
InterceptorStackConfig拦截器栈映射对象;
然后交给ObjectFactory统一创建,具体的是由StrutsObjectFactory进行创建;
protected void loadInterceptorStacks(Element element,
PackageConfig.Builder context) throws ConfigurationException
{
//这句代码的意思是,看看配置文件中哪些拦截器栈被引用了,引用了,就进一步的
//追踪拦截器栈中的拦截器
NodeList
interceptorStackList =
element.getElementsByTagName_r("interceptor-stack");
for (int i = 0; i <
interceptorStackList.getLength(); i++) {
Element interceptorStackElement = (Element)
interceptorStackList.item(i);
InterceptorStackConfig config =
loadInterceptorStack(interceptorStackElement, context);
context.addInterceptorStackConfig(config);
}
}
这最后所有的对象都会跑到ContainerImpl这个容器中,这是struts2的核心容器;即IOC容器;
配置文件默认解析顺序为
default.properties(struts默认的常量信息)--->struts-default.xml--->struts-plugin.xml--->struts.xml;
如果其中有相同信息则后者覆盖前者,因此我们要覆盖struts默认的常量最好是放在struts.xml中的constant元素中;
当然一些插件为了覆盖struts的默认常量也会在对应的struts-plugin.xml中定义常量;并最终汇总到struts.xml中;
总结:核心过滤器的init方法主要做的事:
1 初始化配置文件;
2 初始化核心分发器:Dispatcher
3 初始化PrepareOperations:
他的作用
a:
准备struts的执行环境,具体来说就是创建ActionContext;
b:对request进行包装;
c:action路径的寻址和过滤;
4 初始化ExecuteOperations
他的作用:
a:执行静态资源请求;
b:执行action;
拦截器:只有在action中引用到了,才会在应用加载时创建;
即某个拦截器类出现在interceptor-ref中,才会在初始化的时候被创建;
核心过滤器的init方法的作用;
1
加载并解析配置文件,解析顺序为struts-default.xml,struts-plugin.xml,struts.xml;
如果这三个文件中有相同内容,则后者覆盖前者;配置文件加载后创建struts基本元素:即<bean
type=*,class=*>
结果集合拦截器(只有被引用到的拦截器才会被创建,即interceptor-ref的)
需要注意的是<bean>节点对应的元素,type和class的关系,type:
是父类或者接口,而class是对应的实现类,我们说过配置文件是有加载顺序的,我们要覆盖struts的默认配置
可以在struts.xml,但是覆盖有一个前提,你的实现类,type必须和默认中的type相同;
实现类自己定义,因为在struts调用你的实现类是通过type对应的引用来调用的,实际上的实现类是由你提供的'
这是完全的面向接口(父类)编程,符合开闭原则;比如说
<bean
type="com.opensymphony.xwork2.ObjectFactory" name="struts"
class="org.apache.struts2.impl.StrutsObjectFactory"
/>这是struts中的默认配置,你要修改他的创建模式;
就必须和他继承相同的父类;比如spring集成struts的插件中的struts-plugin.xml配置文件的配置;
<bean type="com.opensymphony.xwork2.ObjectFactory"
name="spring"
class="org.apache.struts2.spring.StrutsSpringObjectFactory"
/>
在struts中一定有这么一行代码:
ObjectFactory objectFactory;并提供相应的set,get方法
然后在使用到的地方直接就是
objectFactory.buildBean();//至于这个buildBean怎么执行不管,但是你的实现类一定要有这个方法;
否则就会导致整个框架的混乱
开闭原则:
实现类你爱怎么实现怎么实现,这是开的一方面;
但是你必须得保证,我父类有的方法一定要有实现;
或者说我的buildBean一定要能执行;这是闭的一方面;
同时配置文件中的内容允许覆盖也正是体现了这点,如果你都不允许他人覆盖你的配置,把什么都写死了,三大框架整合就是
个笑话.
一句话:开闭原则就是对于扩展性我完全开放,但是对于我struts整个的执行流程,谁都不能动,这是我的根基;
2
当请求到来的时候,首先经过核心过滤器的doFilter方法;这个方法实现了以下功能;
a:初始化action执行环境,ActionContext;
对请求url进行解析,并判断你的url是否是需要经过struts的核心;
如果需要做进一步的处理,如果不需要执行chain.doFilter放行;
当然这一步是粗粒度的进行判断,接下来对请求进行包装,解析出对应的action;
并在ActionMapping中找看是否存在对应的action映射;
如果不存在,继续判断是否是要使用到struts的静态资源,即路径中有
"/struts/":对应于org.apache.struts2.template中的静态资源;
"/static/"对应于org.apache.struts2下的static包中的静态资源;
如果有调用静态资源处理器进行处理,如果没有直接放行;
如果
actionMapping中有对应的action;
执行execute.executeAction(request, response,
mapping);方法,进入struts的核心
调用核心分发器的serviceAction方法创建值栈对象ValueStack和contextMap;
并创建出ActionProxy,由ActionProxy创建出ActionInvocation,即核心控制单元,他采用的是command设计模式进行设计;;
由ActionInvocation控制拦截器和action,
和result的执行;
在执行proxy.invoke方法就回到ActionInvocation,由ActionInvocation
负责拦截器的执行,拦截器执行完成后,执行目标action的目标方法,
并返回一个路由串,即结果视图,然后又回到ActionInvocation,继续执行Result中的代码,
result根据配置文件中配置的结果视图类型和页面跳转地址,
这时候通常还得调用jsp等模板对结果进行处理,---是否使用到标签用OGNL解析器进行处理,
形成最终的数据;
然后重新回到ActionInvocation,继续调用
拦截器的清理工作,拦截器都执行完成后,
响应消息写入到response缓冲区,由服务器取出,
以http响应格式输出到浏览器供浏览器解析,
核心过滤器的doFilter方法执行结束,
本次请求结束;ActionContext中的数据被清空;
我们发现核心过滤器和其他过滤器共同构成一个职责链设计模式,整个职责链由tomcat服务器进行控制;
每个过滤器完成自己的功能:1要么直接返回数据到页面
2要么执行完自己的功能后通知下一个过滤器执行;
相关文章推荐
- Spring的总结
- struts2中默认拦截器栈中的拦截器…
- Java内存分析(转载)
- Struts2之Action处理多个方法总结
- Spring框架所有技术笔记总结
- JavaWeb基础回顾
- Struts2的笔记整理与复习
- Struts2.3.7技术的汇总之六(权限…
- 黑马程序员--Struts2.3.7技术的汇…
- 黑马程序员--Struts2.3.7技术的汇…
- 黑马程序员--Struts2.3.7技术的汇…
- Struts2.3.7技术的汇总之三(类型…
- Struts2.3.7技术的汇总之二(注册…
- 黑马程序员--Struts2的常量
- 黑马程序员--Struts2复习笔记
- JDK1.5并发库笔记和总结
- Java一些实用的类(持续更新)
- Java多线程基础知识回顾与总结;
- Java基础笔记的复习与整理---Socke…
- Java基础笔记的复习与整理--集合框…