SpringMVC的servlet分为三层:
分别是DisptcherServlet、FrameworkServlet和HttpServletBean;
下来根据源码主要看下三个的Servlet的主要功能;
先看类继承结构图如下:
部分源码解读:
①:HttpServletBean
继承于HttpServlet
public abstract class HttpServletBean extends HttpServlet {
public final void init() throws ServletException {}
}
重点分析其init()方法
public final void init() throws ServletException {
try {
//主要看下这个类
PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
//获取资源配置,mvc的servlet配置
ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
this.initBeanWrapper(bw);
//为其设置属性
bw.setPropertyValues(pvs, true);
} catch (BeansException var4) {
this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
throw var4;
}
this.initServletBean();
}
获取init参数和属性,为其设置属性
private static class ServletConfigPropertyValues extends MutablePropertyValues {
public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties) throws ServletException {
Set<String> missingProps = requiredProperties != null && !requiredProperties.isEmpty() ? new HashSet(requiredProperties) : null;
Enumeration en = config.getInitParameterNames();
while(en.hasMoreElements()) {
String property = (String)en.nextElement();
Object value = config.getInitParameter(property);
this.addPropertyValue(new PropertyValue(property, value));
if (missingProps != null) {
missingProps.remove(property);
}
}
}
}
所以HttpServletBean主要作用是将Servelt中配置的参数设置到相应的属性
②:FrameworkServlet
该FrameworkServlet继承于HttpServletBean
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {}
看其构造函数,该函数初始化了一个WebAppllicationContext
public FrameworkServlet(WebApplicationContext webApplicationContext) {
this.webApplicationContext = webApplicationContext;
}
WebApplicationContext继承于ApplicationContext这个高级容器
public interface WebApplicationContext extends ApplicationContext {}
所以该FrameworkServlet初始化了一个WebAppllicationContext容器
③:DispatcherServlet
主要作用初始化九大组件
public class DispatcherServlet extends FrameworkServlet {
//这里定义了九大组件分别如下
//上传解析器,用于处理上传请求
public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
//区域解析器,标注视图对应的locale
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
//主题解析器,根据主题名称得到对应的资源
public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
//映射处理器,根据url找到对应的处理器handler,其中保存了url和handler的映射关系
public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
//处理适配器,根据处理器handler对象,适配,执行处理器
public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
//处理异常解析器,用于对异常的处理
public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
//视图名转换器,根据viewName查找对应的view,直接需要转换
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
//视图解析器,根据视图名和locale解析为view类型的视图
public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
//flashMap管理器,主要用于redirect转发
public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
//调用父类FrameworkServlet构造初始化WebApplicationContext
public DispatcherServlet(WebApplicationContext webApplicationContext) {
super(webApplicationContext);
}
//加载9大组件
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);
}
}
9大组件解读
①:multipartResolver 上传解析器,用于处理上传请求
②:localeResolver 区域解析器,用于解析对应的区域,在视图解析器ViewResolver中会用到,和国家化MessageResource中会用到,从request中解析出locale,比如针对美国用户可以提供一个视图,而针对中国用户则可以提供另一个视图。
③:themeResolver 主题解析器,Spring MVC主题包括两部分内容,分别是Theme和ThemeResolver,一个主题对应一个properties文件,里面存放着跟当前主题相关的所有资源,主要是根据主题名找到主题对应的资源。
④:handlerMapping 映射处理器,主要是根据url查找对应的handler处理器,其中保存了url和handler的对应关系
⑤:handlerAdapter 处理适配器,将Handler对象适配到对应的后端控制器(controller)上去
⑥:handlerExceptionResolver 处理异常解析器,对组件中出现的异常进行处理
⑦:viewNameTranslator 视图名转化器,根据viewName查找对应的view,对于handler处理没有返回的,就是直接在url中调用的页面,根据request获取对应的viewName,这些转换都需要在一个Translator里面完成
⑧:viewResolver 视图解析器,用来将对应的视图名viewName和Locale用户区域进行解析为view类型的视图然后进行渲染
⑨:flashMapManager flashMap管理器,用于在redirect中跳转时,将数据保存在flashMap中进行传递,作为重定向之后使用