SpringMVC初始化源码学习

web.xml

<web-app>
    <!--Listener作用:加载并初始化Spring容器(也可以称为父容器)-->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/app-context.xml</param-value>
	</context-param>
 <!--加载并初始化DispatcherServlet(同时也加载并且初始化SpringMVC容器,也称为子容器)-->
	<servlet>
		<servlet-name>app</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value></param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>app</servlet-name>
		<url-pattern>/app/*</url-pattern>
	</servlet-mapping>
 <!--一般情况下只需要一个容器即可,不需要存在这种父子容器,当然这需要根据实际业务需求确定-->
</web-app>

ServletContextListener

在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。

public interface ServletContextListener extends EventListener {
   
    //当Servlet 容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化。
    default void contextInitialized(ServletContextEvent sce) {
   
    }
//当Servlet 容器终止Web 应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet 和Filter 过滤器。
    default void contextDestroyed(ServletContextEvent sce) {
   
    }
}

先初始化Spring容器

ContextLoaderListener
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
   
    public ContextLoaderListener() {
   
    }

    public ContextLoaderListener(WebApplicationContext context) {
   
        super(context);
    }
	//Tomcat启动时,会自动调用该方法,初始化Spring容器
    public void contextInitialized(ServletContextEvent event) {
   
        this.initWebApplicationContext(event.getServletContext());
    }

    public void contextDestroyed(ServletContextEvent event) {
   
        this.closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }
}
ContextLoader
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
   
   		//当前容器已经存在Spring容器,则抛出异常
        if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
   
            throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!");
        } else {
   
            servletContext.log("Initializing Spring root WebApplicationContext");
            Log logger = LogFactory.getLog(ContextLoader.class);
            if (logger.isInfoEnabled()) {
   
                logger.info("Root WebApplicationContext: initialization started");
            }

            long startTime = System.currentTimeMillis();

            try {
   
                if (this.context == null) {
   
                    //创建Spring容器
                    this.context = this.createWebApplicationContext(servletContext);
                }
				//如果context是 ConfigurableWebApplicationContext 这种类型
                if (this.context instanceof ConfigurableWebApplicationContext) {
   
                    ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context;
                    if (!cwac.isActive()) {
   
                        //则设置其父容器
                        if (cwac.getParent() == null) {
   
                            //这里parent 是null
                            ApplicationContext parent = this.loadParentContext(servletContext);
                            cwac.setParent(parent);
                        }
                        //执行Spring容器初始化,加载并初始化Bean
                        this.configureAndRefreshWebApplicationContext(cwac, servletContext);
                    }
                }

              //将Spring放到ServletContext上下文中,使初始化SpringMVC容器时可以拿到Spring容器并且设置为自己的父容器
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
                ClassLoader ccl = Thread.currentThread().getContextClassLoader();
                if (ccl == ContextLoader.class.getClassLoader()) {
   
                    currentContext = this.context;
                } else if (ccl != null) {
   
                    currentContextPerThread.put(ccl, this.context);
                }

                if (logger.isInfoEnabled()) {
   
                    long elapsedTime = System.currentTimeMillis() - startTime;
                    logger.info("Root WebApplicationContext initialized in " + elapsedTime + " ms");
                }

                return this.context;
            } catch (Error | RuntimeException var8) {
   
                logger.error("Context initialization failed", var8);
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var8);
                throw var8;
            }
        }
    }
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
   
        Class<?> contextClass = this.determineContextClass(sc);
        if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
   
            throw new ApplicationContextException("Custom context class [" + contextClass.getName() + "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
        } else {
   
            //利用反射创建Spring容器,这时Spring容器中属性都还没有值,仅仅是new了一个对象出来而已
            return (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass);
        }
    }

初始化SpringMVC容器

DispatcherServlet继承关系

Servlet
// Servlet的加载和实例化可以发生在容器启动时,也可以延迟初始化直到有请求需要处理时
public interface Servlet {
   
     // 负责初始化Servlet对象,容器创建好Servlet对象后由容器调用调用,只执行一次
  	// 当load-on-startup设置为负数或者不设置时会在Servlet第一次用到时才被调用
    void init(ServletConfig var1) throws ServletException;
    // 获取该Servlet的初始化参数信息
    ServletConfig getServletConfig();
    // 负责响应客户端的请求,当容器接收到客户端要求访问特定Servlet对象的请求时,会调用该Servlet对象的service()方法,每次请求都会执行
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    // 返回Servlet信息,包含创建者、版本、版权等信息
    String getServletInfo();
   // Servlet结束生命周期时调用,释放Servlet对象占用的资源
    void destroy();
}
GenericServlet
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
   }
HttpServlet
public abstract class HttpServlet extends GenericServlet {
   }

HttpServletBean

public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
   
	public final void init() throws ServletException {
   
    	// 将init-param映射到bean属性  将<init-param>配置参数自动转换成BeanWrapper
        PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
        if (!pvs.isEmpty()) {
   
            try {
   
                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
                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) {
   
                if (this.logger.isErrorEnabled()) {
   
                    this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
                }

                throw var4;
            }
        }

        this.initServletBean();
    }
}
FrameworkServlet
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
   
	protected final void initServletBean() throws ServletException {
   
        this.getServletContext().log("Initializing Spring " + this.getClass().getSimpleName() + " '" + this.getServletName() + "'");
        if (this.logger.isInfoEnabled()) {
   
            this.logger.info("Initializing Servlet '" + this.getServletName() + "'");
        }

        long startTime = System.currentTimeMillis();

        try {
   
            //初始化SpringMVC容器
            this.webApplicationContext = this.initWebApplicationContext();
            this.initFrameworkServlet();
        } catch (RuntimeException | ServletException var4) {
   
            this.logger.error("Context initialization failed", var4);
            throw var4;
        }

        if (this.logger.isDebugEnabled()) {
   
            String value = this.enableLoggingRequestDetails ? "shown which may lead to unsafe logging of potentially sensitive data" : "masked to prevent unsafe logging of potentially sensitive data";
            this.logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails + "': request parameters and headers will be " + value);
        }

        if (this.logger.isInfoEnabled()) {
   
            this.logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
        }
    }
}
protected WebApplicationContext initWebApplicationContext() {
   
    //从Servlet上下文中获取Spring容器
        WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        WebApplicationContext wac = null;
    //SpringMVC容器不为null
        if (this.webApplicationContext != null) {
   
            wac = this.webApplicationContext;
            if (wac instanceof ConfigurableWebApplicationContext) {
   
                ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac;
                if (!cwac.isActive()) {
   
                    //则设置父容器
                    if (cwac.getParent() == null) {
   
                        cwac.setParent(rootContext);
                    }
                    //加载并初始化SpringMVC中的Bean
                    this.configureAndRefreshWebApplicationContext(cwac);
                }
            }
        }
	//根据ContextAttribute找SpringMVC容器
        if (wac == null) {
   
            wac = this.findWebApplicationContext();
        }
    //如果没有找到,则创建SpringMVC容器
        if (wac == null) {
   
            wac = this.createWebApplicationContext(rootContext);
        }
    //加载并初始化SpringMVC中的Bean
        if (!this.refreshEventReceived) {
   
            synchronized(this.onRefreshMonitor) {
   
                //初始化DispatcherServlet及九大组件
                this.onRefresh(wac);
            }
        }

        if (this.publishContext) {
   
            String attrName = this.getServletContextAttributeName();
            //将SpringMVC容器放入到Servlet上下文中
            this.getServletContext().setAttribute(attrName, wac);
        }

        return wac;
    }
protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {
   
        Class<?> contextClass = this.getContextClass();
        if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
   
            throw new ApplicationContextException("Fatal initialization error in servlet with name '" + this.getServletName() + "': custom WebApplicationContext class [" + contextClass.getName() + "] is not of type ConfigurableWebApplicationContext");
        } else {
   
            //获取利用反射获取SringMVC容器
            ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass);
            //设置系统环境变量
            wac.setEnvironment(this.getEnvironment());
            //设置父容器
            wac.setParent(parent);
            //获取web.xml配置的 contextConfigLocation
            String configLocation = this.getContextConfigLocation();
            if (configLocation != null) {
   
                wac.setConfigLocation(configLocation);
            }

            //加载初始化Bean
            this.configureAndRefreshWebApplicationContext(wac);
            return wac;
        }
    }
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
   
    //设置SpringMVC容器id    
    if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
   
            if (this.contextId != null) {
   
                wac.setId(this.contextId);
            } else {
   
                wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(this.getServletContext().getContextPath()) + '/' + this.getServletName());
            }
        }
//设置Servlet上下文
        wac.setServletContext(this.getServletContext());
    //设置Serlvet一些配置参数
        wac.setServletConfig(this.getServletConfig());
    //设置namespace
        wac.setNamespace(this.getNamespace());
    //设置ContextRefreshListener
        wac.addApplicationListener(new SourceFilteringListener(wac, new FrameworkServlet.ContextRefreshListener()));
    //获取Environment并调用initPropertySources替换servletContextInitParams和servletConfigInitParams参数
        ConfigurableEnvironment env = wac.getEnvironment();
        if (env instanceof ConfigurableWebEnvironment) {
   
            ((ConfigurableWebEnvironment)env).initPropertySources(this.getServletContext(), this.getServletConfig());
        }
//暂无实现
        this.postProcessWebApplicationContext(wac);
        this.applyInitializers(wac);
        wac.refresh();
    }
DispatcherServlet
public class DispatcherServlet extends FrameworkServlet {
   
	protected void onRefresh(ApplicationContext context) {
   
        this.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);
}
private void initLocaleResolver(ApplicationContext context) {
   
        try {
   
            //从Spring容器中获取LocaleResolver的实现类
            this.localeResolver = (LocaleResolver)context.getBean("localeResolver", LocaleResolver.class);
            if (this.logger.isTraceEnabled()) {
   
                this.logger.trace("Detected " + this.localeResolver);
            } else if (this.logger.isDebugEnabled()) {
   
                this.logger.debug("Detected " + this.localeResolver.getClass().getSimpleName());
            }
        } catch (NoSuchBeanDefinitionException var3) {
   
            this.localeResolver = (LocaleResolver)this.getDefaultStrategy(context, LocaleResolver.class);
            if (this.logger.isTraceEnabled()) {
   
                this.logger.trace("No LocaleResolver 'localeResolver': using default [" + this.localeResolver.getClass().getSimpleName() + "]");
            }
        }

    }
 private void initThemeResolver(ApplicationContext context) {
   
        try {
   
            //从Spring容器中获取ThemeResolver的实现类
            this.themeResolver = (ThemeResolver)context.getBean("themeResolver", ThemeResolver.class);
            if (this.logger.isTraceEnabled()) {
   
                this.logger.trace("Detected " + this.themeResolver);
            } else if (this.logger.isDebugEnabled()) {
   
                this.logger.debug("Detected " + this.themeResolver.getClass().getSimpleName());
            }
        } catch (NoSuchBeanDefinitionException var3) {
   
            this.themeResolver = (ThemeResolver)this.getDefaultStrategy(context, ThemeResolver.class);
            if (this.logger.isTraceEnabled()) {
   
                this.logger.trace("No ThemeResolver 'themeResolver': using default [" + this.themeResolver.getClass().getSimpleName() + "]");
            }
        }

    }
private void initHandlerMappings(ApplicationContext context) {
   
		this.handlerMappings = null;
//如果detectAllHandlerMappings为true 则从Spring容器中获取所有实现HandlerMapping接口的实现类
		if (this.detectAllHandlerMappings) {
   
			// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
   
				this.handlerMappings = new ArrayList<>(matchingBeans.values());
				//并且根据@Order注解 进行排序
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}
		else {
   
			try {
   //否则从Spring容器中获取beanName为"handlerMapping"的实现类
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
                //并且赋值给handlerMappings
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {
   
				// Ignore, we'll add a default HandlerMapping later.
			}
		}
//如果handlerMappings还是null
		if (this.handlerMappings == null) {
   
            //则获取默认配置文件配置的HandlerMapping(DispatcherServlet.properties)
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
//遍历所有的HandlerMappings
		for (HandlerMapping mapping : this.handlerMappings) {
   
			if (mapping.usesPathPatterns()) {
   //如果mapping 是自动使用路径匹配
                //则parseRequestPatch设置为true
				this.parseRequestPath = true;
				break;
			}
		}
	}
private void initHandlerAdapters(ApplicationContext context) {
   
		this.handlerAdapters = null;
//如果detectAllHandlerAdapters=true
		if (this.detectAllHandlerAdapters) {
   
			//则从Spring容器中获取所有实现HandlerAdapter接口的实现类
			Map<String, HandlerAdapter> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
			if (!matchingBeans.isEmpty()) {
   
				this.handlerAdapters = new ArrayList<>(matchingBeans.values());
				// 并且根据@Order注解进行排序
				AnnotationAwareOrderComparator.sort(this.handlerAdapters);
			}
		}
		else {
   
			try {
   
                //如果detectAllHandlerAdapters=false,则获取beanName为"handlerAdpater"的handlerApater实现类
				HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
				this.handlerAdapters = Collections.singletonList(ha);
			}
			catch (NoSuchBeanDefinitionException ex) {
   
				// Ignore, we'll add a default HandlerAdapter later.
			}
		}

		//如果handlerApaters==null  则从获取默认配置文件中配置的实现类
		if (this.handlerAdapters == null) {
   
			this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}
private void initHandlerExceptionResolvers(ApplicationContext context) {
   
		this.handlerExceptionResolvers = null;
//如果detectAllHandlerExceptionResolvers=true 则从Spring容器中获取所有实现HandlerExeptionResolver接口的实现类
		if (this.detectAllHandlerExceptionResolvers) {
   
			// Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
					.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
			if (!matchingBeans.isEmpty()) {
   
				this.handlerExceptionResolvers = new ArrayList<>(matchingBeans.values());
				// 根据@Order进行排序
				AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
			}
		}
		else {
   
			try {
   
                //如果detectAllHandlerExceptionResolvers=false 则从spring容器中获取beanName是"handlerExceptionResolver"的实现类
				HandlerExceptionResolver her =
						context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
				this.handlerExceptionResolvers = Collections.singletonList(her);
			}
			catch (NoSuchBeanDefinitionException ex) {
   
				// Ignore, no HandlerExceptionResolver is fine too.
			}
		}

		// 如果handlerExceptionResolvers==null 则获取默认配置文件中默认的实现类
		if (this.handlerExceptionResolvers == null) {
   
			this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("No HandlerExceptionResolvers declared in servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}
private void initRequestToViewNameTranslator(ApplicationContext context) {
   
		try {
   
            //从Spring容器中获取beanName是"viewNameTranslator"的实现类
			this.viewNameTranslator =
					context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("Detected " + this.viewNameTranslator.getClass().getSimpleName());
			}
			else if (logger.isDebugEnabled()) {
   
				logger.debug("Detected " + this.viewNameTranslator);
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
   
			// 如果抛出异常 则获取默认配置文件中配置的实现类
			this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("No RequestToViewNameTranslator '" + REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME +
						"': using default [" + this.viewNameTranslator.getClass().getSimpleName() + "]");
			}
		}
	}
private void initViewResolvers(ApplicationContext context) {
   
		this.viewResolvers = null;
//如果detectAllViewResolvers=true 则从Spring容器获取ViewResolver的实现类
		if (this.detectAllViewResolvers) {
   
			// Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
			Map<String, ViewResolver> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
			if (!matchingBeans.isEmpty()) {
   
				this.viewResolvers = new ArrayList<>(matchingBeans.values());
				// 然后根据@Order进行排序
				AnnotationAwareOrderComparator.sort(this.viewResolvers);
			}
		}
		else {
   
			try {
   
                //如果detectAllViewResolvers=false 则从Spring容器获取beanName是"viewResolver"的实现类
				ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
				this.viewResolvers = Collections.singletonList(vr);
			}
			catch (NoSuchBeanDefinitionException ex) {
   
				// Ignore, we'll add a default ViewResolver later.
			}
		}

		// 如果viewResolvers==null 则获取配置文件中指定默认的ViewResolver实现类
		if (this.viewResolvers == null) {
   
			this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("No ViewResolvers declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}
private void initFlashMapManager(ApplicationContext context) {
   
		try {
   
            //从Spring容器中获取beanName是"flashMapManager"的实现类
			this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("Detected " + this.flashMapManager.getClass().getSimpleName());
			}
			else if (logger.isDebugEnabled()) {
   
				logger.debug("Detected " + this.flashMapManager);
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
   
			// 异常 则从配置文件中获取默认的实现类
			this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class);
			if (logger.isTraceEnabled()) {
   
				logger.trace("No FlashMapManager '" + FLASH_MAP_MANAGER_BEAN_NAME +
						"': using default [" + this.flashMapManager.getClass().getSimpleName() + "]");
			}
		}
	}
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
   
    //defaultStrategies为空 则还没有加载过DispatcherServlet.properties文件
		if (defaultStrategies == null) {
   
			try {
   
				//根据DispatcherServlet.properties 根据ClassPatchRsource
				ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
                //将properties文件内容加载到defaultStrategies中
				defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
			}
			catch (IOException ex) {
   
				throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
			}
		}
//根据传入的参数name 作为key
		String key = strategyInterface.getName();
    //从defaultStrategies(配置文件)中查找
		String value = defaultStrategies.getProperty(key);
		if (value != null) {
   
            //找到 则根据,进行分割,转化为数组
			String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
			List<T> strategies = new ArrayList<>(classNames.length);
			for (String className : classNames) {
   
				try {
   //遍历数组 通过ClassUtils.forName 构建Class
					Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
                    //根据class 创建Bean
					Object strategy = createDefaultStrategy(context, clazz);
                    //添加到strategies集合中
					strategies.add((T) strategy);
				}
				catch (ClassNotFoundException ex) {
   
					throw new BeanInitializationException(
							"Could not find DispatcherServlet's default strategy class [" + className +
							"] for interface [" + key + "]", ex);
				}
				catch (LinkageError err) {
   
					throw new BeanInitializationException(
							"Unresolvable class definition for DispatcherServlet's default strategy class [" +
							className + "] for interface [" + key + "]", err);
				}
			}
            //并返回该集合
			return strategies;
		}
		else {
   
			return Collections.emptyList();
		}
	}

DispatcherServlet.properties


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.function.support.RouterFunctionMapping

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.function.support.HandlerFunctionAdapter


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

相关推荐

  1. SpringMVC初始化学习

    2024-01-31 00:10:02       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-31 00:10:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-31 00:10:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-31 00:10:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-31 00:10:02       18 阅读

热门阅读

  1. Chinese and English names of 45 common character symbols

    2024-01-31 00:10:02       27 阅读
  2. Map和Set

    Map和Set

    2024-01-31 00:10:02      31 阅读
  3. 如何编写.gitignore文件

    2024-01-31 00:10:02       28 阅读
  4. C++入门

    C++入门

    2024-01-31 00:10:02      31 阅读
  5. ESLint代码检查系列 ——入门篇

    2024-01-31 00:10:02       36 阅读
  6. ERD Online后端源码:构建你的数据建模引擎️

    2024-01-31 00:10:02       42 阅读