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 ...
随机推荐
- mysql ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constrain fails
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constrain fails. 可能是MySQL在In ...
- 163邮箱报错WARN: 535 Error: authentication failed.
会让输入自定义授权码..用这个密码代替邮箱的密码,就可以发邮件了.
- springboot学习一:快速搭建springboot项目
1.idea创建springboot工程 JDK选择1.8以上的版本 选择springboot的版本和添加配置项 新建一个HelloController,测试 访问 http://localhost: ...
- mongo 数据查询
基本查询 方法find():查询 db.集合名称.find({条件文档}) 方法findOne():查询,只返回第一个 db.集合名称.findOne({条件文档}) 方法pretty():将结果格式 ...
- 魔力Python——对象
Python之中,一切皆对象. 本文分为4部分: 1. 面向对象:初识 2. 面向对象:进阶 3. 面向对象:三大特性----继承,多态,封装 4. 面向对象:反射 0. 楔子 面向过程和面向对象的是 ...
- 深度学习实践-物体检测-faster-RCNN(原理和部分代码说明) 1.tf.image.resize_and_crop(根据比例取出特征层,进行维度变化) 2.tf.slice(数据切片) 3.x.argsort()(对数据进行排列,返回索引值) 4.np.empty(生成空矩阵) 5.np.meshgrid(生成二维数据) 6.np.where(符合条件的索引) 7.tf.gather取值
1. tf.image.resize_and_crop(net, bbox, 256, [14, 14], name) # 根据bbox的y1,x1,y2,x2获得net中的位置,将其转换为14*1 ...
- python实战:用70行代码写了一个山炮计算器!
python实战训练:用70行代码写了个山炮计算器! 好了...好了...各位因为我是三年级而发牢骚的各位伙伴们,我第一次为大家插播了python的基础实战训练.这个,我是想给,那些python基础一 ...
- Kafka运维填坑(转)
前提: 只针对Kafka 0.9.0.1版本; 说是运维,其实偏重于问题解决; 大部分解决方案都是google而来, 我只是作了次搬运工; 有些问题的解决方案未必一定是通用的, 若应用到线上请慎重; ...
- js中this的绑定规则及优先级
一. this绑定规则 函数调用位置决定了this的绑定对象,必须找到正确的调用位置判断需要应用下面四条规则中的哪一条. 1.1 默认绑定 看下面代码: function foo() { cons ...
- Android Spannable为同一TextView设直不同样式
/** * UNICODE * <p> * 偶尔吃(1-2次/周) ( 中文破弧 * 经常吃(3-5次/周) ( 英文破弧 * * @param name * @return */ pri ...