彻底搞懂 HandlerMapping和HandlerAdapterDispatcherServlet继承 体系
在SpringMvc中,SpringMvc的核心组件DispatcherSerlvet的继承图如上,可以看到上图,其实这个DispatcherServlet终究还是一个Servlet

我们追踪一下他的生命周期创建过程, 首先是说Servlet的创建时机,其实是存在两种情况的, 这取决于.setLoadOnStartup(1);设置的启动级别,当然一般都会设置成正数,表示当容器启动时实例化Servlet

于是Tomcat实例化Servlet,Servlet被初始化时首先被回调的方法是init()这大家都知道的,但是SpringMvc提供的DispatcherServlet中存在一个静态块,源码如下: 这个静态块干了什么事呢? 读取的是class path下面的 DispatcherServlet.properties

Copy
static { // Load default strategy implementations from properties file. // This is currently strictly internal and not meant to be customized // by application developers. try { // todo 它读取的是class path 下面的 DispatcherServlet.properties 配置文件 // todo resource/web/servlet/DispatcherServlet.properties // todo 将这些默认的实现信息,封装进了Properties defaultStrategies ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage()); } }

那问题来了,这个配置文件到底存放的什么? 让DispatcherServlet如此迫切的去加载? 我们文件贴在下面,可以看到存放的是一些全类名,这些是DiapacherServlet针对不同策略接口提供的八个默认的实现,当在上下文中没有匹配到程序员添加的这些实现时,就会使用这些默认的实现

Copy
# Default implementation classes for DispatcherServlet's strategy interfaces. # Used as fallback when no matching beans are found in the DispatcherServlet context. # Not meant to be customized by application developers. # todo 这里存在 DiapacherServlet策略接口的八个默认的实现 # todo 当在上下文中没有匹配到程序员添加的这些实现时,就会使用这些默认的实现 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.method.annotation.RequestMappingHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\ 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

好吧, 虽然这也不算跑题,但是我们还是回到DispatcherServletinit()方法,其实去这个DispatcherServlet中是找不到这个init()方法的, 那这个方法在哪里了呢? 其实就在他的祖父类HttpServletBean中,源码如下:

意图很明确,前面用来初始化环境参数,后者调用initServletBean();

Copy
@Override public final void init() throws ServletException { if (logger.isDebugEnabled()) { logger.debug("Initializing servlet '" + getServletName() + "'"); } // Set bean properties from init parameters. // todo 设置初始化参数 PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); if (!pvs.isEmpty()) {