前面一节描述的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源码解析-----转载的更多相关文章

  1. underscore源码解析 (转载)

    转载出自http://www.cnblogs.com/human/p/3273616.html (function() { // 创建一个全局对象, 在浏览器中表示为window对象, 在Node.j ...

  2. Struts2源码解析2

    看了前面一节对Struts2各个模块运行有了大概了解,也对调用的函数有了一定的了解,本节希望打断点跑一个Struts2例子! 还是放在struts2结构图: 一:项目启动后解析web.xml文件,会解 ...

  3. jQuery整体架构源码解析(转载)

    jQuery整体架构源码解析 最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性, ...

  4. 转载:Bootstrap 源码解析

    Bootstrap 源码解析 前言 Bootstrap 是个CSS库,简单,高效.很多都可以忘记了再去网站查.但是有一些核心的东西需要弄懂.个人认为弄懂了这些应该就算是会了.源码看一波. 栅格系统 所 ...

  5. 【转载】Xutils3源码解析

    Github源码地址:https://github.com/wyouflf/xUtils3 原文地址 :http://www.codekk.com/blogs/detail/54cfab086c476 ...

  6. 【转载】okhttp源码解析

    转自:http://www.open-open.com/lib/view/open1472216742720.html https://blog.piasy.com/2016/07/11/Unders ...

  7. 【转载】FloatingActionButton源码解析

    原文地址:https://github.com/Rowandjj/my_awesome_blog/blob/master/fab_anlysis/README.md loatingActionButt ...

  8. 【转载】Scroller源码解析

    原文地址:https://github.com/Skykai521/AndroidSdkSourceAnalysis/blob/master/article/Scroller%E6%BA%90%E7% ...

  9. 【Caffe】源码解析----caffe.proto (转载)

    分析caffe源码,看首先看caffe.proto,是明智的选择.好吧,我不是创造者,只是搬运工. 原文地址:http://blog.csdn.net/qq_16055159/article/deta ...

随机推荐

  1. 数据泵导出报ORA-01555 ORA-22924

    最近对某数据库执行数据泵导出操作时碰到如下错误:Processing object type DATABASE_EXPORT/SCHEMA/JOBProcessing object type DATA ...

  2. select拼接

    //if (Data1[i].MisFunId == 1) //{ // if (Data1[i].Flag == true) // { // var t = Data1[i].MisFunId; / ...

  3. 使用谷歌CoLaboratory训练神经网络

    前言 Colaboratory 是一个 Google 研究项目,旨在帮助传播机器学习培训和研究成果.它是一个 Jupyter 笔记本环境,不需要进行任何设置就可以使用,并且完全在云端运行.Colabo ...

  4. 基础总结(02)--BFC(块级格式化上下文)

    BFC(块级格式化上下文)布局规则 1.元素垂直排列. 2.同一个BFC相邻两个元素的margin会重叠. 3.BFC区域不会与浮动元素重叠. 4.BFC就是页面上的一个隔离的独立容器,容器里面的子元 ...

  5. Python全栈开发记录_第九篇(面向对象(类)的学习)

    有点时间没更新博客了,今天就开始学习类了,今天主要是面向对象(类),我们知道面向对象的三大特性,那就是封装,继承和多态.内容参考该博客https://www.cnblogs.com/wupeiqi/p ...

  6. 2018-2019-2 20165205 《网络对抗技术》 Exp1 PC平台逆向破解

    2018-2019-2 20165205 <网络对抗技术> Exp1 PC平台逆向破解 1. 实验任务 1.1实验概括 用一个pwn1文件. 该程序正常执行流程是:main调用foo函数, ...

  7. Git的操作理解

    1.本地和远程的关系相当于两个分支,是相互独立的. 2.本地分支属于本地仓库,一个仓库可以包含多个分支. 3.commit是为了告诉Git这次提交我改了哪些东西:       pull是将远程comm ...

  8. 图片转化成base64编码

    var img = "imgurl";//imgurl 就是你的图片路径 function getBase64Image(img) { var canvas = document. ...

  9. app常见性能测试点

    转载自 https://blog.csdn.net/xiaomaoxiao336368/article/details/83547318 1.响应 冷启动 首次启动APP的时间间隔 adb shell ...

  10. jmeter(一)

      jmeter简介   Apache jmeter是Apache组织开发的基于java的压力测试工具   与LR功能基本相同,根据用户数来选择用哪个更合适   为什么要做压力测试? 了解被测系统一般 ...