fuliangliang的Blog

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。

用户操作
[即时聊天] [发私信] [加为好友]
fuliangliangID:fuliangliang
65185次访问,排名1602(1)好友1人,关注者3
fuliangliang的文章
原创 100 篇
翻译 0 篇
转载 25 篇
评论 29 篇
fuliang的公告

我的联系方式:20542606

Email:fuliangliang@gmail.com


最近评论
topgunqq:条理清楚,简单易学.比网上其他例子要好一些.至少按照楼主写的过程,我这个初学者实验成功了!
marshluca:恭喜~~
请问有没rails 做的项目,比方blog?
marshluca@gmail.com
marshluca:恭喜~~
请问有没rails 做的项目,比方blog?
marshluca@gmail.com
chucai:写的非常的好,仔细的拜读了。思路很清晰。考虑的问题也比较全面。
tbsc3:我也遇到了这个问题,如果配1 M就有用,大于2M就还是默认的 不知道你有没有解决呀,教教我
文章分类
收藏
    相册
    净月潭一日游
    页面图片
    日历
    文章收藏
    我的JavaEye博客
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    转载 Spring MVC framework深入分析之三(上)--执行过程 收藏

    新一篇: Spring MVC framework深入分析之三(下)--执行过程 | 旧一篇: Spring MVC framework深入分析二--ApplicationContext之谜

    已经好久没有写Spring MVC深入分析了,心中不免有些愧意。也许可以用做项目、写论文、看书、暑假出去玩等理由作为借口,但是我知道这些都抵不过一个字——懒!呵呵,不过仔细想想,其实这一章的Spring MVC深入分析迟迟未提笔的重要原因是这一章太难写。有时候写抽象的东西会比写具体的东西容易,因此抽象的东西总是会停留在很高的高度,只要心里有想法就可以尽情地释放出来,所以第一章的Spring MVC深入分析我只用了一个下午多就洋洋洒洒地写完了。而写具体的东西却非常容易陷入记流水帐的泥潭,源码分析更是尤为甚之。


    假如去街上找几本Linux源码分析的书,几乎每一本都是源码加注释的方式,哪怕是咱浙大出的那套经典的Linux宝书。也许这样的源码分析会有一定的帮助,尤其是象Linux那么多的代码,也许这样的流水帐式写法是比较现实的。但是当我看了JUnit A Cook's Tour 这样的文章后,我才会发现真正的源码分析不是那么写的,高手能把具体的东西抽象出来,再将这个抽象的思想进行抽丝拨茧式的分析,可以使别人一下子看到了关键,并马上明白了作者的思路和设计思想。

    从具体到抽象正是高手与非高手的重要的区别,一般人的思维总是从具体到具体,最典型的就是看了别人的源码,还不知道怎么回事,就copy过来用。流水帐式的源码分析也是典型的从具体到具体的例子,他没有明白整个系统的设计思想,只是针对具体的每一行代码记下这一行干了什么东西。我不是高手,但是我决定开始装高手,学习高手的想法。假装久了,也便成了高手,呵呵!

    写了一堆闲话,该言归正传啦。其实每个MVC framework的执行过程都是大同小异的,当个request过来时,它都通过一个Servlet来响应request,再根据request的路径名和配置将这个request dispatch给一个Controller执行,最后将之返回配置文件里对应的页面。在Spring MVC里,这个Servlet的名字叫DispatchServlet。稍看一下它的源码会发现这是一很简单的类。

    下面是DispatchServlet的类图:

     

    servlet类图

    简单吧,这是典型的Template Method模式。每个类都会完成一些自己的本职工作,把不属于自己的工作延迟到子类来完成。这些类的子职责在下面会有分析。其实整个SpringFramework用的最多的模式就是Template MethodStrategy也挺多,呵呵),也许任何Framework用的最多的都是Template Method模式。Why?看看Expert One on One J2EE Design and Development至少Template MethodStrategy模式的分析这本书甚至比Head first Design Pattern还好。

    我们先来看DispatchServlet的初始化执行过程分析吧:

    我们知道每个ServletWeb服务器启动时都会有一个初始化的机会,这就是Servletinit过程,这是配置Servlet的最好机会。我们可以在这个阶段干些啥事情呢?

    1、把初始化的那些init-param读到Servlet的属性里。我们知道Servletinit-param是放在ServletConfig里的,我们可以用循环去取这些属性。但是每次都这么干实在太累了,干吗不把在Servlet里增加几个property,再这些init-param直放到Servletproperty里呢?呵呵,以后那些初始参数都可以直接拿来用啦,真方便。DispatchServlet的一个祖先类叫做HttpServletBean就是专门干这个的。以后假如我们要写自己的Servlet也可以直接继承HttpServletBean这个类,这样读ServletConfig的操作都省掉了,哈哈!

    2、从ServletContext里取出ApplicationContext,并扩展成自己的ApplicationContext.

    ApplicationContext之谜里我们已经提到我们可以用Servlet Listner执行的机会把ApplicationContext放到ServletContext中去。但是不是直接拿这个ApplicationContext就足够了呢?no。我们先问一个简单的问题吧:在Spring MVC里我们是不是只能配置一个Servlet呢?Struts就是那么干的,所以在Struts里所有的request过来都会交给一个Servlet去处理。但是在Spring MVC里,我们却可以有好多个Servlet!它们可以处理不同类型的request,而且更重要的是它们的ApplicationContext不是相同的,它们共享了一个父ApplicationContext,也就是从ServletContext里取出来的那个,但是它们却会根据自己的配置作扩展,形成这个Servlet特有的ApplicationContext。这个子的ApplicationContext里有自己的namespace,也就是将一个叫做(假如servlet名称叫xiecc xiecc-servlet.xml的配置文件读进来,行成一个自己的ServletContext。所以这些过程全是在DispatchSevlet的一个父类FrameworkServlet里干的。

    3、初始化接来要干的一件最重要的事情是初始DispatchServlet里的接口。如果用IOC容器的角度来说,其实是将ApplicationContext里定义好的接口注入到一个叫做DispatchServletbean里,只不过这个注入过程是手动的。注入的代码大致如果下(部分角色的含义和作用以后会解释):

    initMultipartResolver();

    initLocaleResolver();

    initThemeResolver();

    initHandlerMappings();

    initHandlerAdapters();

    initHandlerExceptionResolvers();

    initViewResolvers();

    每个init方法其实是属性设置的过程,因为我们可以拿到自己的ApplicationContext,所以这一切都变得很轻松啦。比如说multipartResolver,直接用getWebApplicationContext().getBean(MULTIPART_RESOLVER_BEAN_NAME);就能拿到了。

    不过很多东西在配置文件里是不需要写的,比如说multipartResolver,如果在xml里取不到,Spring会初始化默认的MultipartResolver

     

    接下来我们分析一下DispatchServlet怎么处理Request的执行流程吧:

    看一下DispatchServlet的源码会发现它出奇的简单。简单的原因是类Template MethodStrategy模式,呵呵,这是我取的一个怪名字。因为DispatchServlet是不负责任何具体的操作的,它将具体的操作都delegate给了相应的接口,这是典型的Strategy模式。但是DispatchServlet里的doDispatch方法却控制了执行流程,所有的request过来,我们都会按这样的一个流程处理,这和Template Method里的由父类控制流程不谋而合。所以它仍然是Strategy模式,只不过主类还多了个控制流程的职责。

    所以DispatchServlet本身的doService方法只是负责控制执行流程,而将所有具体的实现细节全都delegate给相应接口,难怪会那么简单。整个流程也异常的简单,我们甚至找不到循环跳转,所有的东西都是一直线下来的,撇开一些细节不说,剩下的就是这以几步了:

    序号

    步骤

    具体内容

    Delegate给谁干?

    1

    准备工作

    设置theme, locale之类的东西。看看Request里是不是要上传文件,如果需要就转成MultipartRequest

     

    2

    request中取到HandlerExecutionChain

    这个过程其实是提交给配置文件里定义的HandlerMapping 来做。HandlerExecutionChain是一个很有趣的东西,它包括就是我们要执行的Controller和一组interceptor,我们把它想象成一个执行单元就行啦。(细节上略有不同,下面会有分析)

    HandlerMapping

    3

    执行HandlerExecutionChain

    其实HandlerExecutionChain里已经包括了要执行的一切东西啦,我们只要把它分解开来执行就行啦。这有点象AOPWebwork的执行方法pre interceptorsàControlleràpostInterceptors

    HandlerExecutionChain,它再delegate给一组interceptor和一个Controller

    4

    执行完的结果拿去显示,也就是所谓的render

    通过ViewResolver的转换后,最后我们会delegate给一个View来完成最后的任务

    ViewResolver

    View

    5

    Render完后还有interceptor

    Spring提供了三个interceptor的机会,前两个Controller方法执行前后

    HandlerExecutionChain里的interceptor


     

    发表于 @ 2006年10月01日 09:16:00|评论(loading...)|编辑

    新一篇: Spring MVC framework深入分析之三(下)--执行过程 | 旧一篇: Spring MVC framework深入分析二--ApplicationContext之谜

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © fuliang