springmvc的入口类为dispatcherServlet,是一个标准的Servlet,在web.xml中配置
继承关系如下
- HttpServlet
- HttpServletBean
- FrameworkServlet
- DispatcherServlet
- FrameworkServlet
- HttpServletBean
Servlet有两大核心方法,init和service
涉及到初始化,肯定是init,但是在DispatcherServlet中并没有init方法,那一定是在父类中了,是的,在HttpServletBean中,简要代码如下
public final void init() throws ServletException { try { //初始化web.xml中配置的init-parms HttpServletBean.ServletConfigPropertyValues ex = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ServletContextResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment())); this.initBeanWrapper(bw); bw.setPropertyValues(ex, true); } catch (BeansException var4) { } //提供扩展点,让子类去实现,扩展初始化 this.initServletBean(); }
在FrameworkServlet中,重写了initServletBean方法,去掉枝节代码,主干如下
protected final void initServletBean() throws ServletException { try { //初始化servlet上下文 this.webApplicationContext = this.initWebApplicationContext(); //提供扩展点 this.initFrameworkServlet(); } catch (Exception var5) { } }
//核心方法,初始化servlet上下文 protected WebApplicationContext initWebApplicationContext() { //通过ServletContext获取根上下文: //servletContext.getAttribute("org.spring.framwork.web.context.webApplication.ROOT") WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); WebApplicationContext wac = null; if(this.webApplicationContext != null) { wac = this.webApplicationContext; if(wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext attrName = (ConfigurableWebApplicationContext)wac; if(!attrName.isActive()) { if(attrName.getParent() == null) { attrName.setParent(rootContext); } this.configureAndRefreshWebApplicationContext(attrName); } } } if(wac == null) { wac = this.findWebApplicationContext(); } if(wac == null) { wac = this.createWebApplicationContext(rootContext); } if(!this.refreshEventReceived) { //提供扩展点,让子类扩展初始化 this.onRefresh(wac); } if(this.publishContext) { String attrName1 = this.getServletContextAttributeName(); this.getServletContext().setAttribute(attrName1, wac); } return wac; }
在DispatcherServlet中,重写了onRefresh方法,onRefresh又委托initStrategies方法,扩展了各种SpringMVC的处理策略。
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); }
至此,初始化也就完毕了。总结一下,
- HttpServlet
- HttpServletBean --init()【初始化web.xml中的init-parms】
- FrameworkServlet --initServletBean(),调用initWebApplicationContext()方法
- DispatcherServlet --onRefresh()【初始化各种处理策略】
- FrameworkServlet --initServletBean(),调用initWebApplicationContext()方法
- HttpServletBean --init()【初始化web.xml中的init-parms】
子类一直在扩展,来完善初始化的功能,这也是模版方法设计模式的应用,更加灵活