fuliangliang的Blog

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

用户操作
[即时聊天] [发私信] [加为好友]
fuliangID:fuliangliang
65467次访问,排名1598好友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深入分析二--ApplicationContext之谜 收藏

    新一篇: Spring MVC framework深入分析之三(上)--执行过程  | 旧一篇: Spring MVC framework深入分析之一--总体分析

    假如我们在写一个基于Spring的普通应用程序,不管我们用了多么精妙的设计模式,进行了如何巧妙的设计,我们必须在某个地方执行这样的代码:

    ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
    new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
    appContext.getBean("…");


    也许这样的代码算不上丑陋,但是它无疑破坏了程序的纯洁性和透明性。我们的应用程序开始显式地依赖SpringFramework,我们必须清楚地知道Spring的配置文件有哪几个,每个配置文件的加入或修改源代码,我们必须在某些代码模块里调用丑陋的getBean方法来创造对象。


    但是所有的这些丑陋的事情似乎在我们的Web应用程序里消失啦,所有的代码都是那么干净,只有简单的get与set及接口之间的调用,我们不需要知道ApplicationContext,我们甚至不需要知道Spring。但是我们所有的对象却又是通过Spring的ApplicationContext来创造的!


    看上去似乎很神奇,但是假如我们稍微思考一下,就会发现这是一件合情合理又如此简单的事情,呵呵,只有第一个想到这个方法的人才是伟大的。让我们仔细想一下普通应用程序和Web应用程序的最大区别在哪里?


    其实真正的区别只有一个,普通应用程序是一个主动执行的程序,而Web应用程序却是被动的组件。这意味着Web应用程序无法自己主动去生成自己的线程去执行某项任务,而必须借用Web容器中的一个线程。想象一下一个简单的任务:我们想每隔一段时间执行一个任务,比如说在Console里打印出一行文字。在我们的Web应用程序里应该怎么完成?在我不知道Servlet Listener或Spring里提供的Schedule之前(其实Spring就是利用Servlet Listner初始化Application Context时启动schedule的),这么简单的任务在一个Web应用程序里竟然是不可想象。还记得我当时采用的是最傻的做法:写了一个单独的应用程序,在这应用程序的main函数里启动了timetask。


    但是如果换一种角度来看,整个Web应用程序生活在容器里也给我们带来了额外的好处,当我们让出了对应用程序的控制权之后,我们可以让容器帮我们完成很多本来很难处理的事情。其实IOC容器的真正作用也在于此,当我们把我们的对象创建工作移交给IOC容器之后,我们发现整个程序变得如此清晰,如此透明,对象之间的关联、哪些类需要事务处理或AOP功能、哪些类要远程访问,所有这些复杂的事情在我们的程序里都不见了,我们只看到了简单的get和set。


    也许废话太多,但我觉得经过这样分析,其实ApplicationContext之谜已经不再是谜了。真正的关键在于当我们的Web应用程序是被动的组件时,它除了可以错用容器的线程之外还可以错用其它一些东西。我们可以让容器来帮我们创建ApplicationContext,然后把它放在某个地方,然后在需要使用时让容器从这个地方把ApplicationContext读出来,并执行相应的Controller就可以了。
    这个"某个地方"就是ServletContext,而这个创建ApplicationContext的地方就是Servlet Listner,而取到ApplicationContext的地方是我们的DispatcherServlet。


    仔细想一下,其实Web服务器并没有什么了不起的地方,它只是一个Java程序,它只是会在启动的时候去ClassLoad某些指定文件夹下的lib或classes,它会读某个在WEB-INF下面一个叫做web.xml的配置文件,再做一些初始化工作。Servlet Listener就是这个初始化工作的重要一步,服务器会读出web.xml里配置好的所有listner,然后调用每个Listner的contextInitialized方法(它还会去调每个Servlet的init方法,不过把初始化方法写在Listner里才是天经地义的)。哈哈,这也正是Spring MVC创建ApplicationContext的最好时机,当我们在web.xml里配置好ContextLoaderListener的时候,Spring就完成了ApplicationContext的创建过程,如果有人想研究源代码的话可以去看一下,不过这个创建过程并不象想象中的那么有趣,只是通过Class.forName和BeanUtils.instantiateClass创建出一个WebApplicationContext,然后再读了一下IOC容器的配置文件。
    接下来的一个问题是我们要把创建的ApplicationContext放在哪里?答案是ServletContext,其实没必须对ServletContext进行深究,它只是可以一个可以全局存放Web应用程序的场所,我们只要想象成一个全局的HashMap就可以了,我们可以要把它put进去,就可以在Servlet或其它地方把它get出来。


    Web服务器还要干的一件事件当然是在某个request到来时,它会启动一个单独的线程(这也是为何Webwork可以把Context放到ThreadLocal里的原因),根据web.xml里的配置和request的URI匹配去执行相应的Servlet。由于Servlet可以很轻松地读到ServletContext,当然也可以很轻松地读到ApplicationContext啦。接下来的事情就比想象中要简单啦,经过一些准备工作之后ApplicationContext中的URLMapping里配置好的某个Controller,执行一下再rend某个view就可以了。其实struts或webwork2的执行过程也是如此,所以MVC framwork分析透了其实真没什么了不起,远比O/R Mapping或其它的framework简单。虽然MVC的执行过程如此简单,但是我们还需要了解一些细节上的事件,所以让我们下次来讨论一下Spring MVC framework的执行过程吧。

     

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

    新一篇: Spring MVC framework深入分析之三(上)--执行过程  | 旧一篇: Spring MVC framework深入分析之一--总体分析

    评论:没有评论。

    发表评论  


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