一、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); }