/** * Name of the class path resource (relative to the DispatcherServlet class) * that defines DispatcherServlet's default strategy names. */ privatestaticfinalStringDEFAULT_STRATEGIES_PATH="DispatcherServlet.properties"; privatestaticfinal Properties defaultStrategies;
static { // Load default strategy implementations from properties file. // This is currently strictly internal and not meant to be customized // by application developers. try { ClassPathResourceresource=newClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { thrownewIllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage()); } }
# 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.
/** * Initialize and publish the WebApplicationContext for this servlet. * <p>Delegates to {@link #createWebApplicationContext} for actual creation * of the context. Can be overridden in subclasses. * @return the WebApplicationContext instance * @see #FrameworkServlet(WebApplicationContext) * @see #setContextClass * @see #setContextConfigLocation */ protected WebApplicationContext initWebApplicationContext() { // <1> 获取根上下文。上下文是具有父子关系的 WebApplicationContextrootContext= WebApplicationContextUtils.getWebApplicationContext(getServletContext()); WebApplicationContextwac=null; // 第一种情况,若Spring成功地使用 构造器注入了 webApplicationContext 实例,则直接使用 if (this.webApplicationContext != null) { // A context instance was injected at construction time -> use it wac = this.webApplicationContext; // 如果是 ConfigurableWebApplicationContext 类型,并且未激活,则进行初始化 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); } // 配置 WebApplicationContex 并发布刷新事件 configureAndRefreshWebApplicationContext(cwac); } } } // 第二种情况,从 ServletContext 获取对应的 WebApplicationContext 对象 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(); } // 第三种,创建一个 WebApplicationContext 对象 if (wac == null) { // No context instance is defined for this servlet -> create a local one wac = createWebApplicationContext(rootContext); }
// <3> 如果未触发刷新事件,则主动触发刷新事件 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. onRefresh(wac); }
// <4> 将 WebApplicationContext 设置到 ServletContext 中 if (this.publishContext) { // Publish the context as a servlet context attribute. StringattrName= getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); if (this.logger.isDebugEnabled()) { this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() + "' as ServletContext attribute with name [" + attrName + "]"); } }
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()); }
/** * {@link org.springframework.context.ApplicationListener} decorator that filters * events from a specified event source, invoking its delegate listener for * matching {@link org.springframework.context.ApplicationEvent} objects only. * * <p>Can also be used as base class, overriding the {@link #onApplicationEventInternal} * method instead of specifying a delegate listener. * * @author Juergen Hoeller * @author Stephane Nicoll * @since 2.0.5 */ publicclassSourceFilteringListenerimplementsGenericApplicationListener, SmartApplicationListener {
/** * Create a SourceFilteringListener for the given event source. * @param source the event source that this listener filters for, * only processing events from this source * @param delegate the delegate listener to invoke with event * from the specified source */ publicSourceFilteringListener(Object source, ApplicationListener<?> delegate) { this.source = source; this.delegate = (delegate instanceof GenericApplicationListener ? (GenericApplicationListener) delegate : newGenericApplicationListenerAdapter(delegate)); }
/** * Create a SourceFilteringListener for the given event source, * expecting subclasses to override the {@link #onApplicationEventInternal} * method (instead of specifying a delegate listener). * @param source the event source that this listener filters for, * only processing events from this source */ protectedSourceFilteringListener(Object source) { this.source = source; }
/** 处理事件 * Actually process the event, after having filtered according to the * desired event source already. * <p>The default implementation invokes the specified delegate, if any. * @param event the event to process (matching the specified source) */ protectedvoidonApplicationEventInternal(ApplicationEvent event) { if (this.delegate == null) { thrownewIllegalStateException( "Must specify a delegate object or override the onApplicationEventInternal method"); } // 调用代理对象的 onApplicationEvent this.delegate.onApplicationEvent(event); }
/** * ApplicationListener endpoint that receives events from this servlet's WebApplicationContext * only, delegating to {@code onApplicationEvent} on the FrameworkServlet instance. */ privateclassContextRefreshListenerimplementsApplicationListener<ContextRefreshedEvent> {
/** * Initialize the strategy objects that this servlet uses. * <p>May be overridden in subclasses in order to initialize further strategy objects. */ protectedvoidinitStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }
/** * Well-known name for the HandlerMapping object in the bean factory for this namespace. * Only used when "detectAllHandlerMappings" is turned off. * @see #setDetectAllHandlerMappings */ publicstaticfinalStringHANDLER_MAPPING_BEAN_NAME="handlerMapping";
/** * Initialize the HandlerMappings used by this class. * <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace, * we default to BeanNameUrlHandlerMapping. */ privatevoidinitHandlerMappings(ApplicationContext context) { this.handlerMappings = null;
//默认为true, 会去检测配置文件中所有的HandlerMapping if (this.detectAllHandlerMappings) { //<1> 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 = newArrayList<>(matchingBeans.values()); //<2> We keep HandlerMappings in sorted order. AnnotationAwareOrderComparator.sort(this.handlerMappings); } } else { // 当为false时,只查找 handlerMapping 这个 bean try { //<3> 根据 bean 名称 和类型查找指定 bean实例。 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. //<4> 如果我们没有配置任何的HandlerMapping对象,则加载默认的 HandlerMapping if (this.handlerMappings == null) { this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default"); } } }
/** * Initialize the HandlerAdapters used by this class. * <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace, * we default to 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()) { this.handlerAdapters = newArrayList<>(matchingBeans.values()); // We keep HandlerAdapters in sorted order. AnnotationAwareOrderComparator.sort(this.handlerAdapters); } } else { try { 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) { this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default"); } } }