if (webAppInitializerClasses != null) { for (Class<?> waiClass : webAppInitializerClasses) { // Be defensive: Some servlet containers provide us with invalid classes, // no matter what @HandlesTypes says... if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) { try { initializers.add((WebApplicationInitializer) ReflectionUtils.accessibleConstructor(waiClass).newInstance()); } catch (Throwable ex) { thrownewServletException("Failed to instantiate WebApplicationInitializer class", ex); } } } }
if (initializers.isEmpty()) { servletContext.log("No Spring WebApplicationInitializer types detected on classpath"); return; }
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath"); AnnotationAwareOrderComparator.sort(initializers); for (WebApplicationInitializer initializer : initializers) { initializer.onStartup(servletContext); } }
protectedvoidregisterDispatcherServlet(ServletContext servletContext) { StringservletName= getServletName(); Assert.hasLength(servletName, "getServletName() must not return null or empty");
//创建springmvc的上下文,注册了MvcContainer类 WebApplicationContextservletAppContext= createServletApplicationContext(); Assert.notNull(servletAppContext, "createServletApplicationContext() must not return null");
//创建DispatcherServlet FrameworkServletdispatcherServlet= createDispatcherServlet(servletAppContext); Assert.notNull(dispatcherServlet, "createDispatcherServlet(WebApplicationContext) must not return null"); dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());
ServletRegistration.Dynamicregistration= servletContext.addServlet(servletName, dispatcherServlet); if (registration == null) { thrownewIllegalStateException("Failed to register servlet with name '" + servletName + "'. " + "Check if there is another servlet registered under the same name."); } /* * 如果该元素的值为负数或者没有设置,则容器会当Servlet被请求时再加载。 * 如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet, * 值越小,servlet的优先级越高,就越先被加载 */ registration.setLoadOnStartup(1); registration.addMapping(getServletMappings()); registration.setAsyncSupported(isAsyncSupported()); //钩子方法获取Servlet监听器 Filter[] filters = getServletFilters(); if (!ObjectUtils.isEmpty(filters)) { for (Filter filter : filters) { //注册servletContext监听器 registerServletFilter(servletContext, filter); } } //扩展点对注册的servlet做修改空方法 customizeRegistration(registration); } ... }
/** * 初始化Spring的web容器 并返回WebApplicationContext * * @param servletContext current servlet context * @return the new WebApplicationContext * @see #ContextLoader(WebApplicationContext) * @see #CONTEXT_CLASS_PARAM * @see #CONFIG_LOCATION_PARAM */ public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { //如果servletContext中有spring父容器报错 if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { thrownewIllegalStateException( "Cannot initialize context because there is already a root application context present - " + "check whether you have multiple ContextLoader* definitions in your web.xml!"); }
servletContext.log("Initializing Spring root WebApplicationContext"); Loglogger= LogFactory.getLog(ContextLoader.class); if (logger.isInfoEnabled()) { logger.info("Root WebApplicationContext: initialization started"); } longstartTime= System.currentTimeMillis();
try { // Store context in local instance variable, to guarantee that // it is available on ServletContext shutdown. if (this.context == null) { //创建spring容器 this.context = createWebApplicationContext(servletContext); } if (this.context instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContextcwac= (ConfigurableWebApplicationContext) this.context; if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() == null) { // The context instance was injected without an explicit parent -> // determine parent for root web application context, if any. ApplicationContextparent= loadParentContext(servletContext); cwac.setParent(parent); } configureAndRefreshWebApplicationContext(cwac, servletContext); } } // 将容器添加到ServletContext上下文 servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
/** * 调用refresh 完成spring容器的启动 * * @param wac * @param sc */ protectedvoidconfigureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // The application context id is still set to its original default value // -> assign a more useful id based on available information StringidParam= sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null) { wac.setId(idParam); } else { // Generate default id... wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } }
// The wac environment's #initPropertySources will be called in any case when the context // is refreshed; do it eagerly here to ensure servlet property sources are in place for // use in any post-processing or initialization that occurs below prior to #refresh ConfigurableEnvironmentenv= wac.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(sc, null); }
if (logger.isDebugEnabled()) { Stringvalue=this.enableLoggingRequestDetails ? "shown which may lead to unsafe logging of potentially sensitive data" : "masked to prevent unsafe logging of potentially sensitive data"; logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails + "': request parameters and headers will be " + value); }
if (logger.isInfoEnabled()) { logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms"); } }
if (this.webApplicationContext != null) { // A context instance was injected at construction time -> use it wac = this.webApplicationContext; if (wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContextcwac= (ConfigurableWebApplicationContext) wac; if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() == null) { // The context instance was injected without an explicit parent -> set // the root application context (if any; may be null) as the parent //设置父子容器 cwac.setParent(rootContext); } //容器加载 configureAndRefreshWebApplicationContext(cwac); } } } if (wac == null) { // No context instance was injected at construction time -> see if one // has been registered in the servlet context. If one exists, it is assumed // that the parent context (if any) has already been set and that the // user has performed any initialization such as setting the context id wac = findWebApplicationContext(); } if (wac == null) { // No context instance is defined for this servlet -> create a local one wac = createWebApplicationContext(rootContext); }
if (!this.refreshEventReceived) { // Either the context is not a ConfigurableApplicationContext with refresh // support or the context injected at construction time had already been // refreshed -> trigger initial onRefresh manually here. synchronized (this.onRefreshMonitor) { //完成刷新 onRefresh(wac); } }
if (this.publishContext) { // Publish the context as a servlet context attribute. StringattrName= getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); }
/** * 调用refresh 完成spring容器的启动 * * @param wac */ protectedvoidconfigureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // The application context id is still set to its original default value // -> assign a more useful id based on available information if (this.contextId != null) { wac.setId(this.contextId); } else { // Generate default id... wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(getServletContext().getContextPath()) + '/' + getServletName()); } }
// The wac environment's #initPropertySources will be called in any case when the context // is refreshed; do it eagerly here to ensure servlet property sources are in place for // use in any post-processing or initialization that occurs below prior to #refresh ConfigurableEnvironmentenv= wac.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig()); } //一个埋点 postProcessWebApplicationContext(wac); applyInitializers(wac); //调用Spring容器的核心方法refresh wac.refresh(); }
/** * Initialize the HandlerMappings used by this class. * <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace, * we default to BeanNameUrlHandlerMapping. * 会加载HandlerMapping,默认使用BeanNameUrlHandlerMapping */ privatevoidinitHandlerMappings(ApplicationContext context) { this.handlerMappings = null;
if (this.detectAllHandlerMappings) { // Find all HandlerMappings in the ApplicationContext, including ancestor contexts. //默认加载所有的HandlerMapping, Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { //数组中含有多个HandlerMapping this.handlerMappings = newArrayList<>(matchingBeans.values()); // We keep HandlerMappings in sorted order. AnnotationAwareOrderComparator.sort(this.handlerMappings); } } else { try { //否则值加载id是handlerMapping或者类型是HandlerMapping的HandlerMapping HandlerMappinghm= context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); this.handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerMapping later. } }
// Ensure we have at least one HandlerMapping, by registering // a default HandlerMapping if no other mappings are found. if (this.handlerMappings == null) { //如果没有合适的handlerMappings获取dispatchServlet.properties默认的HandlerMapping this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isTraceEnabled()) { logger.trace("No HandlerMappings declared for servlet '" + getServletName() + "': using default strategies from DispatcherServlet.properties"); } } }
/** * Initialize the HandlerAdapters used by this class. * <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace, * we default to SimpleControllerHandlerAdapter. * * 初始化HandlerAdapters,默认使用的是SimpleControllerHandlerAdapter */ privatevoidinitHandlerAdapters(ApplicationContext context) { this.handlerAdapters = null;
if (this.detectAllHandlerAdapters) { // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts. Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false); if (!matchingBeans.isEmpty()) { //数组中含有多个HandlerAdapters this.handlerAdapters = newArrayList<>(matchingBeans.values()); // We keep HandlerAdapters in sorted order. AnnotationAwareOrderComparator.sort(this.handlerAdapters); } } else { try { //否则值加载id是handlerAdapter或者类型是HandlerAdapter的HandlerAdapter HandlerAdapterha= context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class); this.handlerAdapters = Collections.singletonList(ha); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerAdapter later. } }
// Ensure we have at least some HandlerAdapters, by registering // default HandlerAdapters if no other adapters are found. if (this.handlerAdapters == null) { //如果没有合适的HandlerAdapter获取dispatchServlet.properties默认的HandlerAdapter this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class); if (logger.isTraceEnabled()) { logger.trace("No HandlerAdapters declared for servlet '" + getServletName() + "': using default strategies from DispatcherServlet.properties"); } } }
if (this.detectAllHandlerExceptionResolvers) { // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts. //默认加载所有的HandlerExceptionResolver Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false); if (!matchingBeans.isEmpty()) { //数组中含有多个HandlerExceptionResolver this.handlerExceptionResolvers = newArrayList<>(matchingBeans.values()); // We keep HandlerExceptionResolvers in sorted order. AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers); } } else { try { //否则值加载id是handlerExceptionResolver或者类型是HandlerExceptionResolver的HandlerExceptionResolver HandlerExceptionResolverher= context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class); this.handlerExceptionResolvers = Collections.singletonList(her); } catch (NoSuchBeanDefinitionException ex) { // Ignore, no HandlerExceptionResolver is fine too. } }
// Ensure we have at least some HandlerExceptionResolvers, by registering // default HandlerExceptionResolvers if no other resolvers are found. if (this.handlerExceptionResolvers == null) { //如果没有合适的HandlerExceptionResolver获取dispatchServlet.properties默认的HandlerExceptionResolver this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class); if (logger.isTraceEnabled()) { logger.trace("No HandlerExceptionResolvers declared in servlet '" + getServletName() + "': using default strategies from DispatcherServlet.properties"); } } }
/** * Translate the given {@link HttpServletRequest} into a view name. * @param request the incoming {@link HttpServletRequest} providing * the context from which a view name is to be resolved * @return the view name, or {@code null} if no default found * @throws Exception if view name translation fails */ @Nullable String getViewName(HttpServletRequest request)throws Exception; }
if (this.detectAllViewResolvers) { // Find all ViewResolvers in the ApplicationContext, including ancestor contexts. //默认加载所有的ViewResolver Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false); if (!matchingBeans.isEmpty()) { //数组中含有多个viewResolvers this.viewResolvers = newArrayList<>(matchingBeans.values()); // We keep ViewResolvers in sorted order. AnnotationAwareOrderComparator.sort(this.viewResolvers); } } else { try { //否则值加载id是viewResolver或者类型是ViewResolver的ViewResolver ViewResolvervr= context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class); this.viewResolvers = Collections.singletonList(vr); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default ViewResolver later. } }
// Ensure we have at least one ViewResolver, by registering // a default ViewResolver if no other resolvers are found. if (this.viewResolvers == null) { //如果没有合适的viewResolvers获取dispatchServlet.properties默认的ViewResolver this.viewResolvers = getDefaultStrategies(context, ViewResolver.class); if (logger.isTraceEnabled()) { logger.trace("No ViewResolvers declared for servlet '" + getServletName() + "': using default strategies from DispatcherServlet.properties"); } } }