struct2源码解读(1)之struts启动
之前用struct2、spring、hibernate在开发一个电子商城,每天都在重复敲代码,感觉对struct2、spring、hibernate的理解都在使用层面上,虽然敲了几个月代码,但是技术水平还是得不到显著提高。于是就想着研究下struct2、spring、hibernate的源码,研究完后不仅对struct2、spring、hibernate加深了了解,同时也加强了java的学习,例如xml的解析,字符操作,线程等等,受益匪浅。想着当初我学习struct2、spring、hibernate源码的时候,网上的学习资源甚少而且杂乱无章,于是就想着把自己的学习心得分享出来,方便大家参考。因本人也在学习之中,如有什么不当之处,希望大家指出;如果大家对某个知识点有更通俗易懂的想法,也希望大家写出来分享。
好了,不多说了,直接上代码吧。特别注意:源码的解读都是建立在一定的基础上的,文中某些知识点我都是默认大家已懂的,就不做过多阐释了;如果大家有什么疑惑,请私信我,我会第一时间为大家做详细的解答。
一、源码准备
struct2是struct与webwork共同努力的成果,因此需要准备struct2的源码和xwork的源码。
因为struct2开发需要导入struct2-core-2.1.8.1.jar和xwork-core-2.1.6.jar 这两个jar包,因此我们需要导入这两个jar包的源码。
如何导入?
最简单的方法,就是在myeclipse去到你的项目,在【referenced libraries】中找到这两个jar包,然后随便双击一个类,双击之后会弹出一个窗口,窗口有个【attach source】按钮,点击然后选中源码资料路径就可以了。
源码资料地址:http://down.51cto.com/data/2113696
阅读源码有很多种办法,比如断点调试追踪、maven、svm等等,而我个人就比较喜欢输入输出法,也就是从struct2的起点开始追踪到它的终点来看。至于用什么方法,都是看个人习惯,没有什么好与不好的。
二、 structs2的启动
(1)struct2的起点
structs2是从哪里开始的呢?
我们在进行struct2开发的时候,需要在web.xml中配置以下一段代码:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
web.xml是tomcat启动时会加载的一个xml文件,这里配置的是一个过滤器,也就是说tomcat启动的时候,会运行StrutsPrepareAndExecuteFilter这个类的init()方法;这就是structs2的起点。
特别注意:FilterDispatcher是早期struts2的过滤器,后期的都用StrutsPrepareAndExecuteFilter了,如 2.1.6、2.1.8。StrutsPrepareAndExecuteFilter名字已经很能说明问题了,prepare与execute,前者表示准备,可以说是指filter中的init方法,即配制的导入;后者表示进行过滤,指doFilter方法,即将request请求,转发给对应的 action去处理。
(2)struct2的初始化
从上面分析可以知道,在tomcat启动的时候,会运行StrutsPrepareAndExecuteFilter这个类的init()方法,这个是struct2的起点,struct2会在这个方法中完成初始化,那么struct2初始化会做一些什么事情呢?
我们来找到这个类,来看下这个类的init()方法。
public void init(FilterConfig filterConfig) throws ServletException { //实例化一个初始化对象 InitOperations init = new InitOperations(); try { FilterHostConfig config = new FilterHostConfig(filterConfig); init.initLogging(config); //实例化一个Dispatcher对象 Dispatcher dispatcher = init.initDispatcher(config); //加载静态资源 init.initStaticContentLoader(config, dispatcher); //实例化两个对象 prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher); execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher); //url黑名单 this.excludedPatterns = init.buildExcludedPatternsList(dispatcher); postInit(dispatcher, filterConfig); } finally { init.cleanup(); } }
InitOperations是struct2设计的 一个用来管理初始化的对象。例如initLogging()初始化日志信息,initDispatcher初始化Dispatcher对象(Dispatcher是struct2的核心对象,这个类准备了struct2运行的环境,包括初始化和action的转发)名字只是一个标记,标记里面的代码是用来干什么的,因此大家在读源码的时候千万不要钻牛角尖,一直纠结这个是什么,哪个又是什么。这些都是struct2设计者对每个代码块的命名罢了。
至于struct2初始化做了什么事情,下一篇博文再做详细的解释。