首页 > 代码库 > Spring源码阅读:Spring MVC 初始化
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中的相关变量即可。