Struts2初始化流程及源码分析

1.1 Struts2初始化

在讲Struts2的初始化之前,应该为大家描述下Web应用中的过滤器Filter,这关系到我们对核心过滤器FilterDispatcher的正确理解。

Filter:一个filter是一个对象,为每个请求资源(一个servlet或静态内容) ,或响应一个资源,或两者,用于执行过滤任务。过滤器执行过滤是在doFilter方法中。每个过滤器方法访问一个FilterConfig对象从中获取初始化参数,filterConfig.getServletContext()可以获得ServletContext对象使用。过滤器的配置在Web应用程序的web.xml中。

init():初始化过滤器,它的输入参数javax.servlet.FilterConfig的一个实例,可以在这里初始化过滤要使用到的FilterConfig。该方法由Web容器自动调用。

doFilter():进行具体的过滤操作,这个方法以javax.servlet.ServletRequest请求信息, javax.servlet.ServletResponse响应信息,javax.servlet.FilterChain过滤链。过滤链,在Web应用程序中所有的过滤器会构成一个链状,符合过滤条件的程序将会根据定义的顺序执行所有链中的过滤器。在这个方法中调用FilterChain的 doFilter(javax.servlet.ServletRequest, javax.servlet.SerletResponse)方法就可以传递到链中的下一个过滤器。

destory():销毁过滤器,可以在这里释放使用完的资源,例如设置过滤器中FilterConfig为null。

综上所述,在Web应用启动时,会默认初始化Filter,调用Filter的init(FilterConfig filterConfig)方法,当请求到来时,会按顺序执行web.xml中所配置Filter的doFilter(ServletRequest req, ServletResponse res, FilterChain chain)方法。

Struts2的核心过滤器FilterDispatcher实现的就是StrutsStatics, Filter接口,所以它本质就是一个过滤器,如下图所示:

image

所以Struts2的初始化工作在Web应用启动时,就可以通过FilterDispatcher核心过滤器init(FilterConfig filterConfig)方法来完成了。如下图所示:

clip_image004

FilterDispatcher.init(FilterConfig filterConfig)方法中主要工作分为:

a) 创建Dispatcher类对象,将FilterDispatcher配置的初始化参数传到该对象中;

b) 加载并解析配置文件,配置文件分为属性配置文件、Bean配置文件两种。Struts2的配置文件包括系统默认的配置文件: default.properties、struts-default.xml,以及插件配置文件、应用配置文件:struts-plugin.xml、struts.xml、struts.properties、web.xml。那么这六种配置文件的加载顺序,如下:

1. default.properties

2. struts-default.xml

3. struts-plugin.xml

4. struts.xml

5. struts.properties

6. web.xml

加载顺序如下图所示:

clip_image006

c) 加载静态资源配置参数: packages,该参数用来配置自动搜寻目录;

小提示:

FilterDispatcher 实现的StrutsStatics接口,没有定义业务方法,只定义了若干个常量。Struts2对常用的接口进行了重新封装,比如HttpServletRequest、HttpServletResponse、HttpServletContext等。如下图所示:

clip_image008

1.2 Struts2初始化源码分析

1. Struts2 Web应用启动时,根据web.xml配置的核心过滤器FilterDispatcher,会初始化FilterDispatcher:

clip_image010

2. 正如我们知道的,过滤器初始化时,会自动调用init()方法进行初始化工作,所以在FilterDispatcher启动时,会自动调用init(FilterConfig filterConfig)方法,进行Struts2的初始化,首先在该方法中会创建org.apache.struts2.Dispatcher对象,将FilterDispatcher配置的初始化参数传到该对象中,然后调用dispatcher.init()方法加载并解析配置文件,最后加载静态资源配置参数packages。org.apache.struts2.dispatcher.FilterDispatcher.java源码如下图所示:

clip_image011

3. 在FilterDispatcher.init()方法中,首先创建Dispatcher类对象,并将FilterDispatcher配置的初始化参数传到对象中;相关代码,如下图所示:

clip_image013

4. 然后通过dispatcher.init()方法,加载并解析Struts2配置文件,配置文件的加载与解析是由Provider类来实现完成的,所以可分为两步:加载配置Provider、解析配置Provider,具体处理步骤如下:

a) 创建com.opensymphony.xwork2.config.ConfigurationManager,其中属性List<ContainerProvider> containerProviders存放所有配置Provider。

b) init_DefaultProperties():初始化一个用来加载default.properties的DefaultPropertiesProvider,并存入至containerProviders。

c) init_TraditionalXmlConfigurations():默认根据struts-default.xml,struts-plugin.xml,struts.xml (可根据init-param:config 修改加载路径) 分别创建三个 org.apache.struts2.config. StrutsXmlConfigurationProvider,并存入至containerProviders。

d) init_LegacyStrutsProperties():初始化初始化一个用来加载struts.properties的LegacyPropertiesConfigurationProvider,并存入至containerProviders。

e) init_CustomConfigurationProviders():根据init-param:configProviders初始化一个用户自定义实现的ConfigurationProvider接口的Provider,并存入至containerProviders。

f) init_FilterInitParameters():初始化一个用来加载web.xml中initParams配置的ConfigurationProvider, 并存入至containerProviders。

g) init_AliasStandardObjects() :初始化一个用来为所配置的Bean与具体类映射的BeanSelectionProvider,并存入至containerProviders。

h) init_PreloadConfiguration():以上几步存入ConfigurationProvider对象完毕后,按顺序循环调用上面几步存入的ConfigurationProvider的register、loadPackages、addPackage方法(先加载先解析),进行解析配置Provider。

小提示:

1. 加载配置Provider,其实就是加载配置文件;

2. 解析配置Provider,其实就是解析配置文件;

下面列出以上a-h步的相关代码,如下图所示:

1. Struts2中dispatcher.init()代码:

clip_image015

2. Struts2中init_PreloadConfiguration()方法代码:

clip_image017

3. XWork中configurationManager.getConfiguration()方法代码:

clip_image019

4. XWork中configuration.reloadContainer()方法代码:

clip_image021

5. Xwork中XmlConfigurationProvider.loadPackages()方法代码:

clip_image023

6. Xwork中XmlConfigurationProvider.addPackage ()方法代码:

clip_image025

4. 最后通过staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig))加载静态资源配置参数:packages,值得注意的是,还有另外三个固定的包和该参数进行拼接,分别是org.apache.struts2.static、template、和org.apache.struts2.interceptor.debugging,中间用空格隔开,经过解析将包名变成路径后存储到一个名叫pathPrefixes的数组中,这些目录中的文件会被自动搜寻;相关代码,如下图所示:

clip_image027

注:

关于源码分析,大概分为两种:流程源码分析、过程源码分析,因本人的初衷是流程源码分析,所以以上的分析是根据初始化处理流程顺序来进行分析的,并未对各个方法的过程细节做深入的讲解,望见谅。

转载于:https://www.cnblogs.com/mktao/archive/2012/08/30/2664296.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379374.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验1 数据库操作

实验1 数据库操作一、实验目的 1.掌握管理工具、T-SQL创建数据库的方法。 2.掌握管理工具、T-SQL修改和查看数据库的方法。 3.掌握管理工具、T-SQL删除数据库的方法。 4.掌握数据库的附加与分离 二、实验要求 1.创建实验所用到的“网上购物系统”数据库eshop。 三、实验内容 1…

Java FileInputStream finalize()方法与示例

FileInputStream类的finalize()方法 (FileInputStream Class finalize() method) finalize() method is available in java.io package. finalize()方法在java.io包中可用。 finalize() method is used to assure that close() method of this FileInputStream invokes when th…

逆风飞扬,吴仁宏

摘自逆风飞扬,吴仁宏自传 它是一个从"生而自卑"到"个性飞扬"的故事&#xff0c;当然具有传奇色彩 中国人几千年都不是天生的赢家&#xff0c;让我们努力&#xff0c;为国为家为自己&#xff0c;做赢家&#xff01; 生存哲学 尼采 痛苦,挫折使生命迁长,使人…

ffmpeg 命令图片和视频相互转换

1当前文件环境&#xff1a; ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.jpg ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.bmp 使用ffplay test.jpb ffplay test.bmp 都是可以打开的 参数介绍&#xff1a; -y 如…

如何点击链接直接跳转到app store指定应用下载页面

转载自&#xff1a;http://blog.csdn.net/zengconggen/article/details/6789420 NSString *str [NSString stringWithFormat:"http://itunes.apple.com/us/app/id%d", 436957167]; [[UIApplication sharedApplication] openURL:[NSURL urlWithString:str]];其中&…

COLLEGE.sql(复制的时候注意路径!!!)

USE [master] GO /****** Object: Database [COLLEGE] Script Date: 2019/11/25 星期一 上午 08:57:11 / CREATE DATABASE [COLLEGE] ON PRIMARY ( NAME N’COLLEGE_m’, FILENAME N’F:\COLLEGE\COLLEGE.mdf’ , SIZE 51200KB , MAXSIZE UNLIMITED, FILEGROWTH 10240KB )…

【管理】「本能叛逆」与「理性叛逆」

叛逆是一般人认知的负面名词&#xff0c;但是&#xff0c;很多人都忽略掉&#xff0c;它却是人类进步的重要因子。观察孩童的成长过程&#xff0c;十岁以后都会出现叛逆行为&#xff0c;相当令父母及师长头痛。然而&#xff0c;叛逆却是促使孩童突破家庭单一环境养成的认知与观…

Java Double类parseDouble()方法的示例

Double类parseDouble()方法 (Double class parseDouble() method) parseDouble() method is available in java.lang package. parseDouble()方法在java.lang包中可用。 parseDouble() method is used to return the double value corresponding to the given String or in oth…

ffmpeg命令 拉流

1&#xff1a; 拉流播放:rtmp &#xff08;ffplay rtmp://server/live/streamName&#xff09; ffplay -x 480 -y 320 rtmp://58.200.131.2:1935/livetv/cctv1 2&#xff1a; 拉流存储到文件:rtmp ffmpeg -i rtmp://58.200.131.2:1935/livetv/cctv1 -codec copy cctvrtmp.f…

小心pthread_cond_signal和SetEvent之间的差异

ZZ FROM: http://blog.csdn.net/absurd/article/details/1402433 转载时请注明出处和作者联系方式&#xff1a;http://blog.csdn.net/absurd 作者联系方式&#xff1a;Li XianJing <xianjimli at hotmail dot com> 更新时间&#xff1a;2006-12-19 今天帮同事查一个多线…

eshop.sql(复制的时候注意路径!!!)

USE [master] GO /****** Object: Database [eshop] Script Date: 2019/11/25 星期一 上午 08:54:14 / CREATE DATABASE [eshop] ON PRIMARY ( NAME N’eshop_dat’, FILENAME N’D:\eshop\eshop_dat.mdf’ , SIZE 10240KB , MAXSIZE 51200KB , FILEGROWTH 5120KB ) LOG O…

doublevalue_Java Double类doubleValue()方法与示例

doublevalueDouble类doubleValue()方法 (Double class doubleValue() method) doubleValue() method is available in java.lang package. doubleValue()方法在java.lang包中可用。 doubleValue() method is used to return the value denoted by this Double object converted…

ffmpeg 命令过滤器裁剪

1 图片操作&#xff1a; 原图&#xff1a; 使用ffplay 显示左半边 ffplay -i input.png -vf cropiw/2:ih:0:0 可以通过ffmpeg 保存 ffmpeg -i input.png -vf cropiw/2:ih:0:0 out.png 2 视频操作&#xff1a; 原视频&#xff1a; 显示左半边 ffplay -i cctvhttp.flv -vf …

去除aspx生成的页面最开始的空行

使用.aspx生成的页面一般都会有一个或多个空行&#xff0c;当然这些空行不会影响页面在浏览器中的渲染结果&#xff0c;不过在查看源代码的时候感觉有些别扭&#xff0c;我曾试着去删除这些空行&#xff0c;但没有成功&#xff0c;你知道你们有没有去尝试。 1 <% Page Langu…

PUBLISH.sql(复制的时候注意路径!!!)

USE [master] – GO – /****** Object: Database [PUBLISH] Script Date: 2019/11/25 星期一 上午 09:00:04 / – CREATE DATABASE [PUBLISH] ON PRIMARY – ( NAME N’PUBLISH’, FILENAME N’F:\PUBLISH\PUBLISH.mdf’ , SIZE 51200KB , MAXSIZE UNLIMITED, FILEGROWTH …

c ++ 函数的esp指针_在C ++中通过指针访问成员函数

c 函数的esp指针Create a class along with data member and member functions and then access the member functions by using a pointer in C. 创建一个类以及数据成员和成员函数&#xff0c;然后使用C 中的指针访问成员函数。 如何通过指针访问成员函数&#xff1f; (How…

[iphone-cocos2d]分享一段Objective-C可调用的游戏中播放音乐(1)

首先需要引入AudioTool 这个framework 代码 -(id)initWithPath:(NSString *)path{ UInt32 size, maxPacketSize; char*cookie; inti; if(gThereIsAnActiveTrack) { NSLog("*** WARNING *** GBMusicTrack only plays one track at a time…

汇编语言-010(循环移位ROL,ROR 、进位循环进位RCL,RCR 、有符号数溢出 、双精度移位SHLD,SHRD、SHL和ADD计算 、位运算应用)

1 &#xff1a;循环移位ROL,ROR,带进位循环进位RCL,RCR .386 .model flat,stdcall.stack 4096 ExitProcess PROTO,dwExitCode:DWORD.code main PROC;循环左移mov al,40h ;AL 010000000brol al,1 ;AL 100000000b ,CF 0rol al,1 ;AL 000000001b ,CF 1rol al,1 ;A…

[Z]POJ 计算几何入门题目推荐[转PKKJ]

http://www.cnblogs.com/eric-blog/archive/2011/05/31/2064785.html http://hi.baidu.com/novosbirsk/blog/item/723a9727a9ab8804918f9dca.html其实也谈不上推荐&#xff0c;只是自己做过的题目而已&#xff0c;甚至有的题目尚未AC&#xff0c;让在挣扎中。之所以推荐计算几何…

2013年 833c语言程序 江南大学 (A卷)

1.编写程序实现求两个整数最大公约数和最小公倍数. 方法一&#xff1a;辗转相除法 算法思路&#xff1a;两个整数a,b,其中a>b&#xff0c;求其最大公约数和最小公倍数 步骤① a%bc,其中c为余数 步骤② 若余数c为0&#xff0c;即a可以把b给整除,也就是说这里的b就是其最大公…