一、DispatcherServlet构造方法
DispatcherServlet有两个构造方法,一个无参数的构造方法和一个WebApplicationContext参数的构造方法,如下代码:
public DispatcherServlet() {
}
public DispatcherServlet(WebApplicationContext webApplicationContext) {
super(webApplicationContext);
}
其中重点看有参数的构造方法,其主要是调用其父类的构造方法,DispatcherServlet是继承父类FrameworkServlet,我们看下FrameworkServlet的构造方法,其代码如下:
public FrameworkServlet(WebApplicationContext webApplicationContext) {
this.contextClass = DEFAULT_CONTEXT_CLASS;
this.publishContext = true;
this.publishEvents = true;
this.threadContextInheritable = false;
this.dispatchOptionsRequest = false;
this.dispatchTraceRequest = false;
this.webApplicationContextInjected = false;
this.refreshEventReceived = false;
this.contextInitializers = new ArrayList();
this.webApplicationContext = webApplicationContext;
}
其中DEFAULT_CONTEXT_CLASS是XmlWebApplicationContext的类,主要是对其中一些属性进行赋值。
二、属性设置
DispatcherServlet通过set方法设置了一些属性,这些属性的默认值都为true,如下:
1、detectAllHandlerMappings
2、detectAllHandlerAdapters
3、detectAllHandlerExceptionResolvers
4、detectAllViewResolvers
5、throwExceptionInfoHandlerFound
6、cleanupAfterInclude
三、初始化
DispatcherServlet中有一个onRefresh方法,其主要调用的是initStrategies(context)方法
再看一下initStrategies(context)方法的源码
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);
}
主要做的是一些文件上传解析器,HandlerMappings等的一些初始化,会调用这些组件的私有初始化方法进行初始化。
例如文件上传解析器初始化initMultipartResolver方法
private void initMultipartResolver(ApplicationContext context) {
try {
this.multipartResolver = (MultipartResolver)context.getBean("multipartResolver", MultipartResolver.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");
}
} catch (NoSuchBeanDefinitionException var3) {
this.multipartResolver = null;
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate MultipartResolver with name 'multipartResolver': no multipart request handling provided");
}
}
}
首先从context中通过getBean方法获取一个multipartResolver对象,并赋值到DispatcherServlet中的mutipartResolver属性中。如果出现异常,会将mutipartResolver属性设为空,并且打印日志。
方法initLocaleResolver和initThemeResolver和其类似。
看一下方法initHandlerMappings(ApplicationContext context)
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList(matchingBeans.values());
OrderComparator.sort(this.handlerMappings);
}
} else {
try {
HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
} catch (NoSuchBeanDefinitionException var3) {
;
}
}
if (this.handlerMappings == null) {
this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("No HandlerMappings found in servlet '" + this.getServletName() + "': using default");
}
}
}
首先将handlerMappings设置为空,创建了一个Map<String,HandlerMapping>,String和HandlerMapping的key-value的map,通过BeanFactoryUtils的方法beansOfTypeIncludingAncestors,这个方法的作用是根据类型寻找bean,找出所有匹配类型的beanName,取出匹配bean的值,放入handlerMappings的ArrayList数组中,并且进行排序,这个排序底层调用的是Collections.sort()的方法,传入了一个OrderComparator的比较器。
如果没有找到handlerMapping,会使用一个默认的BeanNameUrlHandlerMapping,确保有至少有一个HandlerMapping
四、get方法
DispatcherServlet定义了获取这些属性的get方法
五、默认策略方法
创建一个默认的策略,其默认实现使用AutoworeCapableBeanFactory的createBean方法
protected Object createDefaultStrategy(ApplicationContext context, Class<?> clazz) {
return context.getAutowireCapableBeanFactory().createBean(clazz);
}