Spring注解配置启动过程(2)

/**
    * Create the "<strong>root</strong>" application context to be provided to the
    * {@code ContextLoaderListener}.
    * <p>The returned context is delegated to
    * {@link ContextLoaderListener#ContextLoaderListener(WebApplicationContext)} and will
    * be established as the parent context for any {@code DispatcherServlet} application
    * contexts. As such, it typically contains middle-tier services, data sources, etc.
    * @return the root application context, or {@code null} if a root context is not
    * desired
    * @see org.springframework.web.servlet.support.AbstractDispatcherServletInitializer
    */
    protected abstract WebApplicationContext createRootApplicationContext();

/**
    * Specify application context initializers to be applied to the root application
    * context that the {@code ContextLoaderListener} is being created with.
    * @since 4.2
    * @see #createRootApplicationContext()
    * @see ContextLoaderListener#setContextInitializers
    */
    protected ApplicationContextInitializer<?>[] getRootApplicationContextInitializers() {
        return null;
    }

}

注意的是这里我们跳过了AbstractDispatcherServletInitializer抽象类(看uml图),这个类主要配置DispatcherServlet,这里就是spring mvc等功能的实现了。

那谁来加载AbstractContextLoaderInitializer?WebApplicationInitializer已经是接口,不会再有一个抽象类来调用了,于是我尝试性地搜WebApplicationInitializer接口,因为spring这种大项目肯定是面向接口的,所以调用的地方一般是写接口,然后我们找到了SpringServletContainerInitializer类,它实现了ServletContainerInitializer接口,这个类大概是说把所有WebApplicationInitializer都startUp一遍,可以说这个类很接近我们的目标了。下面贴下SpringServletContainerInitializer

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    @Override
    public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
            throws ServletException {

List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();

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) waiClass.newInstance());
                    }
                    catch (Throwable ex) {
                        throw new ServletException("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);
        }
    }

}

在最后的foreach把所有的WebApplicationInitializer都启动一遍。那么问题来了,谁来启动SpringServletContainerInitializer,spring肯定不能自己就能启动的,在

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/2cb7468ecab2ed32cc291d808082f4dd.html