Struts2源码解析-----转载
前面一节描述的Struts2很多东西,这节是对源码进行分析描述,通过这一节应该对struts2有了清楚认识!
还是把Struts2这个框图贴出来:

第一步:HttpServletRequest进入到StrutsPrepareAndExecuteFilter(图上ActionContextCleanUp这个类在集成SiteMesh才有用的其余时候可以不管)
流程图上的FilterDispacther即在web.xml中配置的filter:StrutsPrepareAndExecuteFilter这个是Struts2的核心(下面提到的该类指向这个类),在Struts项目中所有的请求都需要经过它的处理。(注意:更早的版本会有所不同)当每次启动服务器的时候第一次请求都会调用该类的init方法,随后的请求会调用doFilter。如图一我们直接把断点打在doFilter中开始调试。
图一:

根据官方的流程图可以看到请求通过FilterDispacther后会进入到ActionMapper,ActionMapper这个类是一个接口,就是用来匹配当前的请求是否有对应的action。它有4个实现类分别是:RestfulActionMapper,DefaultActionMapper(默认使用),CompositeActionMapper,PrefixBasedActionMapper。
通过ActionMapper得到ActionMapping这个类(图二),ActionMapping对象是用来存放ActionMapper(默认DefaultActionMapper)解析后得到的name,nameSpace,method,extension,params,result 具体可以查看官方文档这边不再赘述。根据图三可以清楚的看到getMapping这个方法就是解析我们的请求来得到ActionMapping,值得一提的是在这个方法中最后调用到的方法parseActionName(图四)有个if判断条件为allowDynamicMethodCalls,这个值的意思就是说是否允许请求使用Struts DMI(动态方法调用例如访问的形式为test!test,意思就是访问test这个对应action中的test方法),Struts配置文件default.properties中默认设置为false,如果你要允许使用DMI就在struts.xml中添加<constant name="struts.enable.DynamicMethodInvocation" value="true"/>。最后通过这个方法后我们得到了ActionMapping。
图二:
图三:
图四:
第二步:StrutsPrepareAndExecuteFilter调用dispatcher类的serviceAction创建ActionProxy
得到ActionMapping后接着执行execute.executeAction方法。此时StrutsPrepareAndExecuteFilter会调用dispatcher这个类的serviceAction(图六),这个方法会对valuStatck等进行处理,重要的是这边会根据ActionMapping这个对象中的属性(前文提到)以及configurationManager(加载Struts2的配置文件)来生成一个ActionProxy如果这个ActionProxy成功创建的话会执行execute方法(图七)反之如果匹配不到Action即无法生成相应的代理对象会返回404页面。
图五:

图六:
图七:
第三步:通过ActionProxy对象调用Actioninvocation的invoke方法执行所有的拦截器
在ActionProxy的execute方法中最后执行的是Actioninvocation(创建ActionProxy过程中默认生成的是它的子类DefaultActionInvocation)的invoke方法。从图八中可以看到从Strtus2从这里开始对拦截器进行处理。这边的interceptors集合在初始化ActionProxy的时候通过配置文件(struts的Struts-default.xml中<interceptor-stack name="defaultStack">)得到。在执行图八中intercept方法时候Struts会把所有的拦截器执行一遍,接着执行请求所指的action中的方法并且按照后进先出的规则执行先前的拦截器(可查看官方流程图)。
下面我们来分析下这个过程。首先通过interceptors.next()获取配置文件中的ExceptionMappingInterceptor对象(这个时候interceptors集合的指针下移也就是说下一次的interceptors.next()指向了AliasInterceptor对象)接着调用ExceptionMappingInterceptor的intercept方法并把当前的DefaultActionInvocation对象作为参数传递进去。而在intercept中又调用了DefaultActionInvocation的invoke方法(图九)接着在剩下的所有拦截器中重复调用Invoke方法直到把所有的拦截器调用完毕。

图八:
图九:
第四步:执行HttpServletRequest对应的Action方法并返回Result
当到了最后一个拦截器DeprecationInterceptor(默认配置情况下最后一个)的时候,此时interceptors.HasNext()为false,因此执行invokeActionOnly方法(图八)。这个方法是用来执行ActionProxy代理的那个Action方法(本次事例为test!add因此对应的Action方法就是add)并获得Result的过程,该过程用了Java的反射机制来实现(图十)。最后按照后进先出的方式依次返回所有拦截器的值最终返回Result视图。
图十:
至此整个Struts2运行流程到此就算是结束了!
到此可能对于这个struts2框架大致运行架构清楚了!
转载于下面这个博客!
https://blog.csdn.net/u010890358/article/details/80245754
https://blog.csdn.net/q547550831/article/details/53267815------struts2系列讲的非常好
Struts2源码解析-----转载的更多相关文章
- underscore源码解析 (转载)
转载出自http://www.cnblogs.com/human/p/3273616.html (function() { // 创建一个全局对象, 在浏览器中表示为window对象, 在Node.j ...
- Struts2源码解析2
看了前面一节对Struts2各个模块运行有了大概了解,也对调用的函数有了一定的了解,本节希望打断点跑一个Struts2例子! 还是放在struts2结构图: 一:项目启动后解析web.xml文件,会解 ...
- jQuery整体架构源码解析(转载)
jQuery整体架构源码解析 最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性, ...
- 转载:Bootstrap 源码解析
Bootstrap 源码解析 前言 Bootstrap 是个CSS库,简单,高效.很多都可以忘记了再去网站查.但是有一些核心的东西需要弄懂.个人认为弄懂了这些应该就算是会了.源码看一波. 栅格系统 所 ...
- 【转载】Xutils3源码解析
Github源码地址:https://github.com/wyouflf/xUtils3 原文地址 :http://www.codekk.com/blogs/detail/54cfab086c476 ...
- 【转载】okhttp源码解析
转自:http://www.open-open.com/lib/view/open1472216742720.html https://blog.piasy.com/2016/07/11/Unders ...
- 【转载】FloatingActionButton源码解析
原文地址:https://github.com/Rowandjj/my_awesome_blog/blob/master/fab_anlysis/README.md loatingActionButt ...
- 【转载】Scroller源码解析
原文地址:https://github.com/Skykai521/AndroidSdkSourceAnalysis/blob/master/article/Scroller%E6%BA%90%E7% ...
- 【Caffe】源码解析----caffe.proto (转载)
分析caffe源码,看首先看caffe.proto,是明智的选择.好吧,我不是创造者,只是搬运工. 原文地址:http://blog.csdn.net/qq_16055159/article/deta ...
随机推荐
- 数据泵导出报ORA-01555 ORA-22924
最近对某数据库执行数据泵导出操作时碰到如下错误:Processing object type DATABASE_EXPORT/SCHEMA/JOBProcessing object type DATA ...
- select拼接
//if (Data1[i].MisFunId == 1) //{ // if (Data1[i].Flag == true) // { // var t = Data1[i].MisFunId; / ...
- 使用谷歌CoLaboratory训练神经网络
前言 Colaboratory 是一个 Google 研究项目,旨在帮助传播机器学习培训和研究成果.它是一个 Jupyter 笔记本环境,不需要进行任何设置就可以使用,并且完全在云端运行.Colabo ...
- 基础总结(02)--BFC(块级格式化上下文)
BFC(块级格式化上下文)布局规则 1.元素垂直排列. 2.同一个BFC相邻两个元素的margin会重叠. 3.BFC区域不会与浮动元素重叠. 4.BFC就是页面上的一个隔离的独立容器,容器里面的子元 ...
- Python全栈开发记录_第九篇(面向对象(类)的学习)
有点时间没更新博客了,今天就开始学习类了,今天主要是面向对象(类),我们知道面向对象的三大特性,那就是封装,继承和多态.内容参考该博客https://www.cnblogs.com/wupeiqi/p ...
- 2018-2019-2 20165205 《网络对抗技术》 Exp1 PC平台逆向破解
2018-2019-2 20165205 <网络对抗技术> Exp1 PC平台逆向破解 1. 实验任务 1.1实验概括 用一个pwn1文件. 该程序正常执行流程是:main调用foo函数, ...
- Git的操作理解
1.本地和远程的关系相当于两个分支,是相互独立的. 2.本地分支属于本地仓库,一个仓库可以包含多个分支. 3.commit是为了告诉Git这次提交我改了哪些东西: pull是将远程comm ...
- 图片转化成base64编码
var img = "imgurl";//imgurl 就是你的图片路径 function getBase64Image(img) { var canvas = document. ...
- app常见性能测试点
转载自 https://blog.csdn.net/xiaomaoxiao336368/article/details/83547318 1.响应 冷启动 首次启动APP的时间间隔 adb shell ...
- jmeter(一)
jmeter简介 Apache jmeter是Apache组织开发的基于java的压力测试工具 与LR功能基本相同,根据用户数来选择用哪个更合适 为什么要做压力测试? 了解被测系统一般 ...