SpringMVC的启动
Spring MVC中的Servlet
Spring MVC中Servlet一共有三个层次,分别是HttpServletBean、FrameworkServlet和DispatcherServlet。HttpServletBean直接继承自Java的HttpServlet,其作用是将Servlet中配置的参数设置到相应的属性;FrameworkServlet初始化了WebApplicationContext;DispatcherServlet初始化了自身的9个组件。
DispatcherServlet
DispatcherServlet的入口方法是onRefresh方法,其中简单地调用了initStrategies方法,其中又调用了9个初始化方法,初始化策略组件。
protected void onRefresh(ApplicationContext context) {
this.initStrategies(context);
}
onRefresh
protected void initStrategies(ApplicationContext context) {
// 上传组件
this.initMultipartResolver(context);
// 国际化组件
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
initStrategies
// 以initLocaleResolver为例分析初始化组件过程
private void initLocaleResolver(ApplicationContext context) {
try {
// 按照名称或类型在容器中获取
// 我们只要在SpringMVC的配置文件中配置相应类型的组件,容器就可以自动找到
this.localeResolver = (LocaleResolver)context.getBean("localeResolver", LocaleResolver.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
}
} catch (NoSuchBeanDefinitionException var3) {
// 如果没有配置,使用默认策略
this.localeResolver = (LocaleResolver)this.getDefaultStrategy(context, LocaleResolver.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate LocaleResolver with name 'localeResolver': using default [" + this.localeResolver + "]");
}
}
}
initLocaleResolver
protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {
// 调用复数的方法
List<T> strategies = this.getDefaultStrategies(context, strategyInterface);
if (strategies.size() != 1) {
throw new BeanInitializationException("DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]");
} else {
// 返回第一个
return strategies.get(0);
}
}
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
String key = strategyInterface.getName();
// Properties类型的defaultStrategies在静态代码块中初始化
String value = defaultStrategies.getProperty(key);
if (value == null) {
return new LinkedList();
} else {
// 如果有多个默认值,以逗号分隔数组
String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
List<T> strategies = new ArrayList(classNames.length);
String[] var7 = classNames;
int var8 = classNames.length;
// 初始化组件
for(int var9 = 0; var9 < var8; ++var9) {
String className = var7[var9];
try {
Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
Object strategy = this.createDefaultStrategy(context, clazz);
strategies.add(strategy);
} catch (ClassNotFoundException var13) {
throw new BeanInitializationException("Could not find DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", var13);
} catch (LinkageError var14) {
throw new BeanInitializationException("Error loading DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]: problem with class file or dependent class", var14);
}
}
return strategies;
}
}
static {
try {
// DispatcherServlet.properties在DispatcherServlet.java文件的旁边
ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException var1) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + var1.getMessage());
}
}
DispatcherServlet.properties文件内容:
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
一共定义了8个组件,上传组件MultipartResolver没有默认配置,因为不是每个应用都需要上传功能,即使需要上传也不一定就要使用MultipartResolver;HandlerMapping、HandlerAdapter和HandlerExceptionResolver都配置了多个;ViewResolver也可以配置多个,默认是一个。
默认配置并不是最优配置,也不是spring的推荐配置。
当使用<mvc:annotation-driven/>后,并不会全部使用默认配置,因为它配置了HandlerMapping、HandlerAdapter和HandlerExceptionResolver,而且还做了很多别的工作。
Spring MVC的启动
启动DispatcherServlet之前先创建HttpServletBean、FrameworkServlet,创建DispatcherServlet后调用其onRefresh方法,再调用initStrategies方法初始化其它组件。
SpringMVC的启动的更多相关文章
- 如何让springmvc在启动的时候执行特定的业务处理
如何让springmvc在启动的时候执行特定的业务处理 java 的 web服务器启动时,经常会做一些特定的业务逻辑处理,比如数据库初始化, 初始化系统参数,读取配置文库等. 很多web服务的中间件, ...
- SpringMVC——项目启动时从数据库查询数据
SpringMVC项目中遇到这样的问题: 1.很多数据字典需要从数据库中查询: 2.懒得修改SQL语句: 3.想在项目中声明静态变量存储数据字典,但是希望这个字典可以在项目启动时进行加载. 当遇到这样 ...
- SpringMVC DispatcherServlet 启动和加载过程(源码调试)
在阅读本文前,最好先阅读以下内容(当然,如果对 Servlet 已经有所了解,则可跳过): http://www.cnblogs.com/cyhbyw/p/8682078.html http://ww ...
- SpringMVC的启动过程
前言 下面是一个SpringMVC应用的配置文件,需要注意两个地方,一个是ContextLoaderListener,一个是dispatcherServlet.web容器正是通过这两个配置才和spri ...
- Spring/SpringMVC在启动完成后执行方法
在某些情况下,有可能你会有这种需求:在Spring/SpringMVC项目中,当Spring/SpringMVC启动完成后,你需要执行一个方法来完成某些事件(比如创建网站地图,比如从订阅Redis服务 ...
- 第一篇:spring+springMVC项目启动最终笔记(一web.xml)
1.web应用启动从web.xml开始,首先创建一个全局的上下文(Context),名字叫ServletContext,可以理解为一间图书馆,或一个数据结构(如map,但是比map牛多了),整个结构类 ...
- maven+springmvc项目启动时,request mapping not found……
springmvc项目跑的好好的,跑着跑着,出现request mapping not found的问题. 第一波,网上查问题,stackoverflow上面的各种配置说明,但是我本地就是没查出问题 ...
- SpringMVC Tomcat 启动时报错:java.lang.IllegalStateException: Error starting child
大概原因如下: 1.Controller里RequestMapping("/test")前面没有"/"; 2.jar包冲突,比如我的将数据库连接版本由5.1.6 ...
- Spring之SpringMVC(源码)启动初始化过程分析
1.说明 SpringMVC作为Spring提供的MVC实现,可以实现与Spring的天然无缝联合,因为具有很广泛的用途.具体的关于SpringMVC的处理流程逻辑我在这里就不在赘述了.还是来通过源码 ...
随机推荐
- 2019年19道java经典面试题(附答案)
1.不可变对象 指对象一旦被创建状态不能再改变.任何修改都会创建一个新的对象,如 String.Integer及其它包装类. 2.能否创建一个包含可变对象的不可变对象? 可以.不要共享可变对象的引用就 ...
- web自动化测试---web页面元素的定位
selenium提供了很多用于定位元素的方法,首先我们自己需要知道元素有哪些属性,这就需要用到安装测试环境中firebug来定位 打开firefox浏览器,按下F12键,我们就可以看到如下图所示的界面 ...
- mongodb 语句和SQL语句对应(SQL to Aggregation Mapping Chart)
SQL to Aggregation Mapping Chart https://docs.mongodb.com/manual/reference/sql-aggregation-compariso ...
- listview监听组件内容变化
package com.meizu.ui.gifts; import android.app.Activity; import android.content.Context; import andr ...
- 使用配置文件自定义Ribbon配置
1.application.yml——Ribbon配置文件 debug: false spring: application: name: mcc-ribbon-properties cloud: c ...
- jquery根据name属性查找元素
$("div[id]") //选择所有含有id属性的div元素 $("input[name='newsletter']") //选择所有的name属性等于'ne ...
- Python机器学习笔记:深入理解Keras中序贯模型和函数模型
先从sklearn说起吧,如果学习了sklearn的话,那么学习Keras相对来说比较容易.为什么这样说呢? 我们首先比较一下sklearn的机器学习大致使用流程和Keras的大致使用流程: skl ...
- vuex状态管理之学习笔记
概述及使用场景 Vuex 是一个主要应用在中大型单页应用的类似于 Flux 的数据管理架构.它主要帮我们更好地组织代码,以及把应用内的的状态保持在可维护.可理解的状态. 但如果是简单的应用 ,就没有必 ...
- nginx配置指南
nginx(读作engine x)是一款设计优秀的Http服务器, 其占用内存少, 负载能力强且稳定性高, 正在被越来越多的用户所采用. nginx可以为HTTP, HTTPS, SMTP, POP3 ...
- 前端MVC Vue2学习总结(八)——Vue Router路由、Vuex状态管理、Element-UI
一.Vue Router路由 二.Vuex状态管理 三.Element-UI Element-UI是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架,手机端有对应框架是 Mint U ...