Spring源码阅读:Spring MVC 初始化

通过之前的源码学习,了解了Spring的两个核心IOC和AOP。也了解到系统初始化时,就已经将所有applicationContext.xml中的bean Definintion加载并初始化了。

如果使用了SpringMVC框架,MVC框架指定的namespace-servlet.xml也已经被初始化了。

使用过SpringMVC,都知道需要在web.xml配置配置DispatcherServlet,它是处理请求的入口。Servlet是单例的,系统指挥在第一次处理用户请求时初始化Servlet对象。那么DispatcherServlet初始化时都做了哪些工作呢?我们在namespace-servlet.xml中配置的视图解析器,注解处理器都是怎样被DispatcherServlet使用的呢?

DispatcherServlet的类型继承关系:

通过对DispatcherServlet及其父类的源码的阅读,了解到初始化的过程是这个样子的:

也就是说初始化DispatcherServlet的过程中要调用到DispatcherServlet对象的initStrategies()方法,下面来看看这个方法都干了啥:

DispatcherServlet定义了这些变量:

/** MultipartResolver used by this servlet */

   private MultipartResolver multipartResolver;

   /** LocaleResolver used by this servlet */

   private LocaleResolver localeResolver;

   /** ThemeResolver used by this servlet */

   private ThemeResolver themeResolver;

   /** List of HandlerMappings used by this servlet */

   private List<HandlerMapping> handlerMappings;

   /** List of HandlerAdapters used by this servlet */

   private List<HandlerAdapter> handlerAdapters;

   /** List of HandlerExceptionResolvers used by this servlet */

   private List<HandlerExceptionResolver> handlerExceptionResolvers;

   /** RequestToViewNameTranslator used by this servlet */

   private RequestToViewNameTranslator viewNameTranslator;

   /** List of ViewResolvers used by this servlet */

   private List<ViewResolver> viewResolvers;

initStrategies就是要初始化DispaterServlet中的变量的:

protected void initStrategies(ApplicationContext context) {

      initMultipartResolver(context);

      initLocaleResolver(context);

      initThemeResolver(context);

      initHandlerMappings(context);

      initHandlerAdapters(context);

      initHandlerExceptionResolvers(context);

      initRequestToViewNameTranslator(context);

      initViewResolvers(context);

   }

这样就有疑问了:Servlet应该是一个无状态的类才能保证Servlet对象的线程安全性。而DispatcherServlet中定义了这么多变量,这样DispatcherServlet就不是线程就安全的类了。

其实这个担忧是不必要的,在initStrategies方法中,是将DispatcherServlet中定义的变量进行初始化,这个方法只会调用一次,而在整个系统中,也只有这一个地方会调用这个方法。所以initStrategies内部的几个方法也只会被调用一次。而正是这一次调用就将相关的变量全部赋值。所以是不用担心线程安全的问题。

这个方法为啥要传递一个ApplicationContext参数呢?

经过之前对于IOC容器初始化的分析了解到,在IOC初始化时,就已经将所有的Bean初始化了,这里要做的是将那些初始化完毕的bean从IOC容器ApplicationContext获取(context.getBean("beanName"))然后赋值给DispatcherServlet中的相关变量即可。

Spring源码阅读:Spring MVC 初始化

时间: 2024-08-24 03:39:32

Spring源码阅读:Spring MVC 初始化的相关文章

Spring源码阅读:Spring MVC 如何处理HTTP请求

Spring MVC 对HTTP请求的处理流程 通过之前的源码阅读,知道了ApplicationContext初始的过程,也知道了Spring MVC环境的初始化过程,今天就来了解一下SpringMVC是如何处理HTTP请求的. HTTP请求根据请求方式可以分为GET.POST.PUT.DELETE.OPTIONS.TRACE,最常用的还是GET和POST. Spring对于这几种HTTP请求的处理都是使用了processRequest(req,rep); @Override protected

Spring源码阅读:Spring WebApplicationContext初始化与消亡

使用SpringMVC时,需要不论是使用注解配置,还是使用XML配置Bean,他们都会在Web服务器启动后就初始化.根据J2ee的知识可以知道,肯定是使用了ServletContextListener才完成的这个功能.那Spring又是如何实现的呢?还有我们在Web.xml配置的那些applicationContext.xml相关的XML文件的位置(配置方式多样),又是如何读取到相应的文件的呢,读取到这些文件后,是如何初始化类的呢?我们能不能自定义初始化过程或者自定义WebApplication

Spring源码阅读系列总结

最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重要的设计模式简单的做了阐述.同时还会简单的加入一些GOF中提到的设计原则.Spring的源码阅读系列,也暂告一段落.下面是就带你走进Spring世界: Spring系列的引子 1)Spring WebApplicationContext初始化与消亡 这一节帮我们了解Spring是如何初始化WebAp

Spring源码阅读:IOC容器的设计与实现(二)——ApplicationContext

上一主题中,了解了IOC容器的基本概念,以及BeanFactory的设计与实现方式,这里就来了解一下ApplicationContext方式的实现. ApplicationContext 在Spring的参考文档中,为啥要推荐使用ApplicationContext?它能给我们的应用带来什么好处呢?作为BeanFactory的实现之一,它又是如何设计的?在SpringMVC中使用的WebApplictionContext\XmlApplicationContext与之有何关联? Applicat

Spring源码阅读:Spring JDBC 组件的设计与实现

昨天回忆了我在学习JDBC时自己设计的JDBCTemplate(写在上一篇博客中),在使用Spring过程中,有时会用到Spring给我们提供的JdbcTemplate,这里看看Spring是如何实现这个组件的. 在使用Spring JDBC是你要做的工作很少: 从上面的图上可以看出来,使用Spring JDBC,你只需要做四个工作: 1)定义连接参数:也就是定义url,driver,user,password这个几个参数,一般我们会用一个jdbc.properties文件来配置. 2)指定要执

Spring源码阅读:使用标准AOP的API模拟Spring AOP + AspectJ的设计与实现

在上一篇博客中,提到了标准AOP与Spring AOP.这一篇就来把他们模拟出来. 在模拟之前,还需要提及的是,在Spring框架中,对于AOP的支持: Spring 支持的AOP AspectJ是另外一个有名的AOP框架,Spring也集成AspectJ,同时Spring AOP与AspectJ有一定程度的集成,这样一来Spring中就支持两种AOP:1)Spring AOP.2)AspectJ.而使用AOP的方式却又三种: 1)完全使用Spring AOP 2)完全使用AspectJ(分为注

spring源码阅读(2)-- 容器启动之加载BeanDefinition

在<spring源码阅读(1)-- 容器启动之资源定位>一文中,阅读了spring是怎么根据用户指定的配置加载资源,当加载完资源,接下来便是把从资源中加载BeanDefinition. BeanDefinition作为spring其中一个组件,spring是这样描述BeanDefinition的:BeanDefinition描述了一个bean实例,它具有属性值,构造函数参数值以及具体实现提供的更多信息.个人的理解是BeanDefinition保存了一个bean实例的所有元数据,下面列举一些常用

Spring源码阅读:Spring声明式事务处理和编程式事务处理的设计与实现

之前的学习,了解了Spring事务管理的基础框架(查看).Spring在此基础上又提到了声明式事务管理和编程式事务管理.这里就来看看Spring是如何实现的. Spring声明式事务与EJB事务管理对比 Spring的声明式管理,类似于EJB的CMT,但又有不同.他们的不同之处有: 1)EJB的CMT是与JTA结合使用,而Spring框架的声明式事务管理可以在任何环境下工作.既可以使用全局事务管理,如JTA,也可以使用局部事务管理如JDBCJPA.Hibernate.JDO等. 2)可以在任何类

Spring源码阅读:Spring如何支持各种ORM框架

为了让开发程序更容易,到现在为止,已经有很多ORM框架了,例如:JPA,JDO,Hibernate,Mybatis(之前版本是IBatis)等等.也正因为已经有这么多优秀的ORM框架,Spring团队并没有自己开发一套ORM框架,而是对这些框架都进行了支持,让这些框架在Spring环境下可以得到完全的应用. 通常,在Spring环境下使用这些ORM框架时,都会通过一个Template来使用.Spring对这些框架的集成是这样的: 例如Hibernate,在使用Hibernate时(没有在Spri