- 浏览: 740486 次
- 性别:
- 来自: 郑州
文章分类
- 全部博客 (396)
- JAVA (50)
- ORACLE (22)
- HIBERNATE (1)
- SPRING (26)
- STRUTS (4)
- OTHERS (0)
- MYSQL (11)
- Struts2 (16)
- JS (33)
- Tomcat (6)
- DWR (1)
- JQuery (26)
- JBoss (0)
- SQL SERVER (0)
- XML (10)
- 生活 (3)
- JSP (11)
- CSS (5)
- word (1)
- MyEclipse (7)
- JSTL (1)
- JEECMS (2)
- Freemarker (8)
- 页面特效 (1)
- EXT (2)
- Web前端 js库 (2)
- JSON http://www.json.org (3)
- 代码收集 (1)
- 电脑常识 (6)
- MD5加密 (0)
- Axis (0)
- Grails (1)
- 浏览器 (1)
- js调试工具 (1)
- WEB前端 (5)
- JDBC (2)
- PowerDesigner (1)
- OperaMasks (1)
- CMS (1)
- Java开源大全 (2)
- 分页 (28)
- Eclipse插件 (1)
- Proxool (1)
- Jad (1)
- Java反编译 (2)
- 报表 (6)
- JSON (14)
- FCKeditor (9)
- SVN (1)
- ACCESS (1)
- 正则表达式 (3)
- 数据库 (1)
- Flex (3)
- pinyin4j (2)
- IBATIS (3)
- probe (1)
- JSP & Servlet (1)
- 飞信 (0)
- AjaxSwing (0)
- AjaxSwing (0)
- Grid相关 (1)
- HTML (5)
- Guice (4)
- Warp framework (1)
- warp-persist (1)
- 服务器推送 (3)
- eclipse (1)
- JForum (5)
- 工具 (1)
- Python (1)
- Ruby (1)
- SVG (3)
- Joda-Time日期时间工具 (1)
- JDK (3)
- Pushlet (2)
- JSP & Servlet & FTP (1)
- FTP (6)
- 时间与效率 (4)
- 二维码 (1)
- 条码/二维码 (1)
最新评论
-
ctrlc:
你这是从web服务器上传到FTP服务器上的吧,能从用户电脑上上 ...
jsp 往 FTP 上传文件问题 -
annybz:
说的好抽象 为什么代码都有两遍。这个感觉没有第一篇 和第二篇 ...
Spring源代码解析(三):Spring JDBC -
annybz:
...
Spring源代码解析(一):IOC容器 -
jie_20:
你确定你有这样配置做过测试? 请不要转载一些自己没有测试的文档 ...
Spring2.0集成iReport报表技术概述 -
asd51731:
大哥,limit传-1时出错啊,怎么修改啊?
mysql limit 使用方法
上面我们分析了IOC容器本身的实现,下面我们看看在典型的web环境中,Spring IOC容器是怎样被载入和起作用的。
简单的说,
在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是
根上下文,这个上下文持有的对象可以有业务对象,数据存取对象,资源,事物管理器等各种中间层对象。在这个上下文的基础上,和web
MVC相关还会有一个上下文来保存控制器之类的MVC对象,这样就构成了一个层次化的上下文结构。在web容器中启动Spring应用程序就是一个建立这
个上下文体系的过程。Spring为web应用提供了上下文的扩展接口
WebApplicationContext:
- public interface WebApplicationContext extends ApplicationContext {
- //这里定义的常量用于在ServletContext中存取 根上下文
- String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext. class .getName() + ".ROOT" ;
- ......
- //对WebApplicationContext来说,需要 得到Web容器的ServletContext
- ServletContext getServletContext();
- }
public interface WebApplicationContext extends ApplicationContext { //这里定义的常量用于在ServletContext中存取根上下文 String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT"; ...... //对WebApplicationContext来说,需要得到Web容器的ServletContext ServletContext getServletContext(); }
而一般的启动过程,Spring会使用一个默认的实现,XmlWebApplicationContext -
这个上下文实现作为在web容器中的根上下文容器被建立起来,具体的建立过程在下面我们会详细分析。
- public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
- /** 这是和web部署相关的位置信息,用来作为默认的根上 下文bean定义信息的存放位置*/
- public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml" ;
- public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/" ;
- public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml" ;
- //我们又看到了熟悉的 loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。
- protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
- //对于 XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析
- XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
- beanDefinitionReader.setResourceLoader( this );
- beanDefinitionReader.setEntityResolver( new ResourceEntityResolver( this ));
- initBeanDefinitionReader(beanDefinitionReader);
- loadBeanDefinitions(beanDefinitionReader);
- }
- protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
- }
- //使用XmlBeanDefinitionReader来读 入bean定义信息
- protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
- String[] configLocations = getConfigLocations();
- if (configLocations != null ) {
- for ( int i = 0 ; i < configLocations.length; i++) {
- reader.loadBeanDefinitions(configLocations[i]);
- }
- }
- }
- //这里取得bean定义信息位置,默认的地方是/WEB- INF/applicationContext.xml
- protected String[] getDefaultConfigLocations() {
- if (getNamespace() != null ) {
- return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
- }
- else {
- return new String[] {DEFAULT_CONFIG_LOCATION};
- }
- }
- }
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { /** 这是和web部署相关的位置信息,用来作为默认的根上下文bean定义信息的存放位置*/ public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; //我们又看到了熟悉的loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException { //对于XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); } protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { } //使用XmlBeanDefinitionReader来读入bean定义信息 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { String[] configLocations = getConfigLocations(); if (configLocations != null) { for (int i = 0; i < configLocations.length; i++) { reader.loadBeanDefinitions(configLocations[i]); } } } //这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml protected String[] getDefaultConfigLocations() { if (getNamespace() != null) { return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX}; } else { return new String[] {DEFAULT_CONFIG_LOCATION}; } } }
对于一个Spring激活的web应用程序,可以通过使用Spring代码声明式的指定在web应用程序启动时载入应用程序上下文
(WebApplicationContext),Spring的ContextLoader是提供这样性能的类,我们可以使用
ContextLoaderServlet或者ContextLoaderListener的启动时载入的Servlet来实例化Spring
IOC容器 - 为什么会有两个不同的类来装载它呢,这是因为它们的使用需要区别不同的Servlet容器支持的Serlvet版本。但不管是
ContextLoaderSevlet还是
ContextLoaderListener都使用ContextLoader来完成实际的WebApplicationContext的初始化工作。这
个ContextLoder就像是Spring
Web应用程序在Web容器中的加载器booter。当然这些Servlet的具体使用我们都要借助web容器中的部署描述符来进行相关的定义。
下
面我们使用ContextLoaderListener作为载入器作一个详细的分析,这个Servlet的监听器是根上下文被载入的地方,也是整个
Spring web应用加载上下文的第一个地方;从加载过程我们可以看到,首先从Servlet事件中得到ServletContext,然后可以读到
配置好的在web.xml的中的各个属性值,然后ContextLoder实例化WebApplicationContext并完成其载入和初始化作为根
上下文。当这个根上下文被载入后,它被绑定到web应用程序的ServletContext上。任何需要访问该ApplicationContext的应
用程序代码都可以从WebApplicationContextUtils类的静态方法来得到:
WebApplicationContext getWebApplicationContext(ServletContext sc)
以Tomcat作为Servlet容器为例,下面是具体的步骤:
1.Tomcat
启动时需要从web.xml中读取启动参数,在web.xml中我们需要对ContextLoaderListener进行配置,对于在web应用启动入
口是在ContextLoaderListener中的初始化部分;从Spring
MVC上看,实际上在web容器中维护了一系列的IOC容器,其中在ContextLoader中载入的IOC容器作为根上下文而存在于
ServletContext中。
- //这里对根上下文进行初始化。
- public void contextInitialized(ServletContextEvent event) {
- //这里创建需要的ContextLoader
- this .contextLoader = createContextLoader();
- //这里使用ContextLoader对根上下文进行载入和 初始化
- this .contextLoader.initWebApplicationContext(event.getServletContext());
- }
//这里对根上下文进行初始化。 public void contextInitialized(ServletContextEvent event) { //这里创建需要的ContextLoader this.contextLoader = createContextLoader(); //这里使用ContextLoader对根上下文进行载入和初始化 this.contextLoader.initWebApplicationContext(event.getServletContext()); }
通过ContextLoader建立起根上下文的过程,我们可以在ContextLoader中看到:
- public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
- throws IllegalStateException, BeansException {
- //这里先看看是不是已经在ServletContext中存 在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。
- if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null ) {
- //直接抛出异常
- .........
- }
- ...............
- try {
- // 这里载入根上下文的父上下文
- ApplicationContext parent = loadParentContext(servletContext);
- //这里创建根上下文作为整个应用的上下文同时把它存 到ServletContext中去,注意这里使用的ServletContext的属性值是
- //ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, 以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文
- this .context = createWebApplicationContext(servletContext, parent);
- servletContext.setAttribute(
- WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this .context);
- ..........
- return this .context;
- }
- ............
- }
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) throws IllegalStateException, BeansException { //这里先看看是不是已经在ServletContext中存在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。 if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { //直接抛出异常 ......... } ............... try { // 这里载入根上下文的父上下文 ApplicationContext parent = loadParentContext(servletContext); //这里创建根上下文作为整个应用的上下文同时把它存到ServletContext中去,注意这里使用的ServletContext的属性值是 //ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文 this.context = createWebApplicationContext(servletContext, parent); servletContext.setAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); .......... return this.context; } ............ }
建立根上下文的父上下文使用的是下面的代码,取决于在web.xml中定义的参数:locatorFactorySelector,这是一
个可选参数:
- protected ApplicationContext loadParentContext(ServletContext servletContext)
- throws BeansException {
- ApplicationContext parentContext = null ;
- String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
- String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
- if (locatorFactorySelector != null ) {
- BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
- ........
- //得到根上下文的父上下文的引用
- this .parentContextRef = locator.useBeanFactory(parentContextKey);
- //这里建立得到根上下文的父上下文
- parentContext = (ApplicationContext) this .parentContextRef.getFactory();
- }
- return parentContext;
- }
protected ApplicationContext loadParentContext(ServletContext servletContext) throws BeansException { ApplicationContext parentContext = null; String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM); String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM); if (locatorFactorySelector != null) { BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); ........ //得到根上下文的父上下文的引用 this.parentContextRef = locator.useBeanFactory(parentContextKey); //这里建立得到根上下文的父上下文 parentContext = (ApplicationContext) this.parentContextRef.getFactory(); } return parentContext; }
得到根上下文的父上下文以后,就是根上下文的创建过程:
- protected WebApplicationContext createWebApplicationContext(
- ServletContext servletContext, ApplicationContext parent) throws BeansException {
- //这里需要确定我们载入的根WebApplication的 类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext,
- //如果没有使用默认的。
- Class contextClass = determineContextClass(servletContext);
- .........
- //这里就是上下文的创建过程
- ConfigurableWebApplicationContext wac =
- (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
- //这里保持对父上下文和ServletContext的引用 到根上下文中
- wac.setParent(parent);
- wac.setServletContext(servletContext);
- //这里从web.xml中取得相关的初始化参数
- String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
- if (configLocation != null ) {
- wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
- ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
- //这里对WebApplicationContext进行初始 化,我们又看到了熟悉的refresh调用。
- wac.refresh();
- return wac;
- }
protected WebApplicationContext createWebApplicationContext( ServletContext servletContext, ApplicationContext parent) throws BeansException { //这里需要确定我们载入的根WebApplication的类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext, //如果没有使用默认的。 Class contextClass = determineContextClass(servletContext); ......... //这里就是上下文的创建过程 ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); //这里保持对父上下文和ServletContext的引用到根上下文中 wac.setParent(parent); wac.setServletContext(servletContext); //这里从web.xml中取得相关的初始化参数 String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocation != null) { wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation, ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); } //这里对WebApplicationContext进行初始化,我们又看到了熟悉的refresh调用。 wac.refresh(); return wac; }
初始化根ApplicationContext后将其存储到SevletContext中去以后,这样就建立了一个全局的关于整个应用的上
下文。这个根上下文会被以后的DispatcherServlet初始化自己的时候作为自己ApplicationContext的父上下文。这个在对
DispatcherServlet做分析的时候我们可以看看到。
3.完成对ContextLoaderListener的初始化以
后, Tomcat开始初始化DispatchServlet,-
还记得我们在web.xml中队载入次序进行了定义。DispatcherServlet会建立自己的ApplicationContext,同时建立这
个自己的上下文的时候会从ServletContext中得到根上下文作为父上下文,然后再对自己的上下文进行初始化,并最后存到
ServletContext中去供以后检索和使用。
可以从DispatchServlet的父类FrameworkServlet的代码中看
到大致的初始化过程,整个ApplicationContext的创建过程和ContextLoder创建的过程相类似:
- protected final void initServletBean() throws ServletException, BeansException {
- .........
- try {
- //这里是对上下文的初始化过程。
- this .webApplicationContext = initWebApplicationContext();
- //在完成对上下文的初始化过程结束后,根据bean 配置信息建立MVC框架的各个主要元素
- initFrameworkServlet();
- }
- ........
- }
protected final void initServletBean() throws ServletException, BeansException { ......... try { //这里是对上下文的初始化过程。 this.webApplicationContext = initWebApplicationContext(); //在完成对上下文的初始化过程结束后,根据bean配置信息建立MVC框架的各个主要元素 initFrameworkServlet(); } ........ }
对initWebApplicationContext()调用的代码如下:
- protected WebApplicationContext initWebApplicationContext() throws BeansException {
- //这里调用 WebApplicationContextUtils静态类来得到根上下文
- WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
- //创建当前DispatcherServlet的上下文,其 上下文种类使用默认的在FrameworkServlet定义好 的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
- WebApplicationContext wac = createWebApplicationContext(parent);
- ........
- if (isPublishContext()) {
- //把当前建立的上下文存到 ServletContext中去,注意使用的属性名是和当前Servlet名相关的。
- String attrName = getServletContextAttributeName();
- getServletContext().setAttribute(attrName, wac);
- }
- return wac;
- }
protected WebApplicationContext initWebApplicationContext() throws BeansException { //这里调用WebApplicationContextUtils静态类来得到根上下文 WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); //创建当前DispatcherServlet的上下文,其上下文种类使用默认的在FrameworkServlet定义好的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class; WebApplicationContext wac = createWebApplicationContext(parent); ........ if (isPublishContext()) { //把当前建立的上下文存到ServletContext中去,注意使用的属性名是和当前Servlet名相关的。 String attrName = getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); } return wac; }
其中我们看到调用了WebApplicationContextUtils的静态方法得到根ApplicationContext:
- public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
- //很简单,直接从ServletContext中通 过属性名得到根上下文
- Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
- .......
- return (WebApplicationContext) attr;
- }
- 然后创建DispatcherServlet自己的WebApplicationContext:
- protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
- throws BeansException {
- .......
- //这里使用了BeanUtils直接得到 WebApplicationContext,ContextClass是前面定义好的 DEFAULT_CONTEXT_CLASS =
- //XmlWebApplicationContext.class;
- ConfigurableWebApplicationContext wac =
- (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
- //这里配置父上下文,就是在 ContextLoader中建立的根上下文
- wac.setParent(parent);
- //保留ServletContext的引用和相关的 配置信息。
- wac.setServletContext(getServletContext());
- wac.setServletConfig(getServletConfig());
- wac.setNamespace(getNamespace());
- //这里得到ApplicationContext配 置文件的位置
- if (getContextConfigLocation() != null ) {
- wac.setConfigLocations(
- StringUtils.tokenizeToStringArray(
- getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
- //这里调用ApplicationContext的 初始化过程,同样需要使用refresh()
- wac.refresh();
- return wac;
- }
public static WebApplicationContext getWebApplicationContext(ServletContext sc) { //很简单,直接从ServletContext中通过属性名得到根上下文 Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); ....... return (WebApplicationContext) attr; } 然后创建DispatcherServlet自己的WebApplicationContext: protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) throws BeansException { ....... //这里使用了BeanUtils直接得到WebApplicationContext,ContextClass是前面定义好的DEFAULT_CONTEXT_CLASS = //XmlWebApplicationContext.class; ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass()); //这里配置父上下文,就是在ContextLoader中建立的根上下文 wac.setParent(parent); //保留ServletContext的引用和相关的配置信息。 wac.setServletContext(getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace()); //这里得到ApplicationContext配置文件的位置 if (getContextConfigLocation() != null) { wac.setConfigLocations( StringUtils.tokenizeToStringArray( getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); } //这里调用ApplicationContext的初始化过程,同样需要使用refresh() wac.refresh(); return wac; }
4. 然后就是DispatchServlet中对Spring MVC的配置过程,首先对配置文件中的定义元素进行配置 -
请注意这个时候我们的WebApplicationContext已经建立起来了,也意味着DispatcherServlet有自己的定义资源,可以需
要从web.xml中读取bean的配置信息,通常我们会使用单独的xml文件来配置MVC中各个要素定义,这里和web容器相关的加载过程实际上已经完
成了,下面的处理和普通的Spring应用程序的编写没有什么太大的差别,我们先看看MVC的初始化过程:
- protected void initFrameworkServlet() throws ServletException, BeansException {
- initMultipartResolver();
- initLocaleResolver();
- initThemeResolver();
- initHandlerMappings();
- initHandlerAdapters();
- initHandlerExceptionResolvers();
- initRequestToViewNameTranslator();
- initViewResolvers();
- }
protected void initFrameworkServlet() throws ServletException, BeansException { initMultipartResolver(); initLocaleResolver(); initThemeResolver(); initHandlerMappings(); initHandlerAdapters(); initHandlerExceptionResolvers(); initRequestToViewNameTranslator(); initViewResolvers(); }
5. 这样MVC的框架就建立起来了,DispatchServlet对接受到的HTTP
Request进行分发处理由doService()完成,具体的MVC处理过程我们在doDispatch()中完成,其中包括使用Command模式
建立执行链,显示模型数据等,这些处理我们都可以在DispatcherServlet的代码中看到:
- protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
- ......
- try {
- doDispatch(request, response);
- }
- .......
- }
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { ...... try { doDispatch(request, response); } ....... }
实际的请求分发由doDispatch(request,response)来完成:
- protected void doDispatch( final HttpServletRequest request, HttpServletResponse response) throws Exception {
- .......
- // 这是Spring定义的执行链,里面放了映射关系对应 的handler和定义的相关拦截器。
- HandlerExecutionChain mappedHandler = null ;
- ......
- try {
- //我们熟悉的ModelAndView在这里出 现了。
- ModelAndView mv = null ;
- try {
- processedRequest = checkMultipart(request);
- //这里更具request中的参数和映 射关系定义决定使用的handler
- mappedHandler = getHandler(processedRequest, false );
- ......
- //这里是handler的调用过程,类 似于Command模式中的execute.
- HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
- mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
- .......
- //这里将模型数据通过视图进行展现
- if (mv != null && !mv.wasCleared()) {
- render(mv, processedRequest, response);
- }
- ........
- }
protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception { ....... // 这是Spring定义的执行链,里面放了映射关系对应的handler和定义的相关拦截器。 HandlerExecutionChain mappedHandler = null; ...... try { //我们熟悉的ModelAndView在这里出现了。 ModelAndView mv = null; try { processedRequest = checkMultipart(request); //这里更具request中的参数和映射关系定义决定使用的handler mappedHandler = getHandler(processedRequest, false); ...... //这里是handler的调用过程,类似于Command模式中的execute. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); ....... //这里将模型数据通过视图进行展现 if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); } ........ }
这样具体的MVC模型的实现就由bean配置文件里定义好的view resolver,handler这些类来实现用户代码的功能。
总
结上面的过程,我们看到在web容器中,ServletContext可以持有一系列的web上下文,而在整个web上下文中存在一个根上下文来作为其它
Servlet上下文的父上下文。这个根上下文是由ContextLoader载入并进行初始化的,对于我们的web应用,
DispatcherSerlvet载入并初始化自己的上下文,这个上下文的父上下文是根上下文,并且我们也能从ServletContext中根据
Servlet的名字来检索到我们需要的对应于这个Servlet的上下文,但是根上下文的名字是由Spring唯一确定的。这个
DispactcherServlet建立的上下文就是我们开发Spring MVC应用的IOC容器。
具体的web请求处理在上下文体系建立
完成以后由DispactcherServlet来完成,上面对MVC的运作做了一个大致的描述,下面我们会具体就SpringMVC的框架实现作一个详
细的分析。
发表评论
-
Spring--quartz中cronExpression配置说明
2011-12-02 18:28 0quartz中cronExpression配置说明 字段 ... -
使用Spring的jdbcTemplate进一步简化JDBC操作
2011-12-02 09:20 1234先看applicationContext.xml配置文件: ... -
Spring MVC:使用SimpleUrlHandlerMapping的一个简单例子
2011-12-01 11:26 942实现一个控制器ShirdrnCon ... -
最简单的Spring MVC入门示例
2010-05-19 14:29 1494应一位朋友的要求,写一个最简单的spring示例,使用s ... -
Spring源代码解析(十):Spring Acegi框架授权的实现
2010-03-18 12:48 1491我们从FilterSecurityIntercep ... -
Spring源代码解析(九):Spring Acegi框架鉴权的实现
2010-03-18 12:47 1471简单分析一下Spring Acegi的源代码实现: Ser ... -
Spring源代码解析(八):Spring驱动Hibernate的实现
2010-03-18 12:41 1397O/R工具出现之后,简化了许多复杂的信息持久化的开发。Spri ... -
Spring源代码解析(七):Spring AOP中对拦截器调用的实现
2010-03-18 12:40 1385前面我们分析了Spring AOP实现中得到Proxy对象的过 ... -
Spring源代码解析(六):Spring声明式事务处理
2010-03-18 12:37 1069我们看看Spring中的事务处理的代码,使用Spring管理事 ... -
Spring源代码解析(五):Spring AOP获取Proxy
2010-03-18 12:36 1291下面我们来看看Spring的AOP的一些相关代码是怎么得到Pr ... -
Spring源代码解析(四):Spring MVC
2010-03-18 12:35 7691下面我们对Spring MVC框架代码进行分析,对于web ... -
Spring源代码解析(三):Spring JDBC
2010-03-18 12:33 1657下面我们看看Spring JDBC相关的实现, 在Spri ... -
Spring源代码解析(一):IOC容器
2010-03-18 12:30 2632在Spring中,IOC容器的重要地位我们就不多说了,对于Sp ... -
使用Spring的JdbcTemplate和BeanPropertyRowMapper完成的JDBC
2010-03-18 12:08 2228先道要加上两个包:Spring2.5下面的: spring. ... -
使用Spring的SimpleJdbcTemplate完成DAO操作
2010-03-18 12:06 1473l SimpleJdbcTemplate内部包含了 ... -
使用Spring的NamedParameterJdbcTemplate完成DAO操作
2010-03-18 12:05 1383NamedParameterJdbcTemplate内部包含了 ... -
Spring in Action 学习笔记—第四章 征服数据库(转)
2010-03-18 12:03 1226Spring2.0正式版(http://www.springf ... -
Spring管理JDBC连接
2010-03-18 11:59 1658在Spring中,JdbcTemplate是经常被使用的类来帮 ... -
Spring JDBC数据库操作类
2010-03-18 09:26 16081.JdbcTemplate 在Spring中, ... -
Spring JdbcTemplate 批量插入或更新操作
2010-03-18 09:19 5224用 JdbcTemplate 进行批量插入或更新操作 ...
相关推荐
Spring源代码解析(一):IOC容器.doc
Spring源代码解析(二):IoC容器在Web容器中的启动.doc
Spring源代码解析2:IoC容器在Web容器中的启动.doc Spring源代码解析3:Spring JDBC .doc Spring源代码解析4:Spring MVC .doc Spring源代码解析5:Spring AOP获取Proxy .doc Spring源代码解析6:Spring声明式事务...
Spring源代码解析2:IoC容器在Web容器中的启动;Spring源代码解析3:Spring JDBC ; Spring源代码解析4:Spring MVC ;Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; ...
Spring源代码解析(二):IoC容器在Web容器中的启动 Spring源代码解析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务...
Spring源代码解析2:IoC容器在Web容器中的启动;Spring源代码解析3:Spring JDBC ; Spring源代码解析4:Spring MVC ;Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; ...
Spring源代码解析(二):ioc容器在Web容器中的启动 Spring源代码分析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理...
Spring源代码解析(二):ioc容器在Web容器中的启动 3.Spring源代码解析(三):Spring JDBC 4.Spring源代码解析(四):Spring MVC 5.Spring源代码解析(五):Spring AOP获取Proxy 6. Spring源代码解析(六):Spring...
Spring源代码解析(二):ioc容器在Web容器中的启动.doc Spring源代码分析(三):Spring JDBC.doc Spring源代码解析(四):Spring MVC.doc Spring源代码解析(五):Spring AOP获取Proxy.doc Spring源代码解析(六):...
简单的说,在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是根上下文,这个上下文持有的对象可以有业务对象,数据存取对象,资源,事物管理...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
spring如何在web环境中集成ioc容器并为web应用开发提供利器? 我们耳熟能详的mvc模式在spring中是如何实现的? spring mvc如何灵活地集成各种丰富的视图展现方案? spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
spring如何在web环境中集成ioc容器并为web应用开发提供利器? 我们耳熟能详的mvc模式在spring中是如何实现的? spring mvc如何灵活地集成各种丰富的视图展现方案? spring实现远端调用的方案有很多种,你...
spring如何在web环境中集成ioc容器并为web应用开发提供利器? 我们耳熟能详的mvc模式在spring中是如何实现的? spring mvc如何灵活地集成各种丰富的视图展现方案? spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...