Loading

系列文章:spring的xml配置是如何对应注解配置的之ContextLoaderListener

何时加载ContextLoaderListener?

ContextLoaderListener:继承ContextLoader,实现ServletContextListener,接收web应用ServletContext变化的通知,将监听器配置在web.xml中。我们一般会在xml中做如下配置:

<!-- 默认的spring配置文件是在WEB-INF下的applicationContext.xml -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:bean.xml
    </param-value>
</context-param>

以spring boot启动为例

  1. 由子类实现的onRefresh
ServletWebServerApplicationContext
@Override
protected void onRefresh() {
    super.onRefresh();
    try {
        createWebServer();
    }
    catch (Throwable ex) {
        throw new ApplicationContextException("Unable to start web server", ex);
    }
}
  1. 创建web容器
private void createWebServer() {
    WebServer webServer = this.webServer;
    ServletContext servletContext = getServletContext();
    if (webServer == null && servletContext == null) {
        ServletWebServerFactory factory = getWebServerFactory();
        this.webServer = factory.getWebServer(getSelfInitializer());
    }
    else if (servletContext != null) {
        try {
            getSelfInitializer().onStartup(servletContext);
        }
        catch (ServletException ex) {
            throw new ApplicationContextException("Cannot initialize servlet context", ex);
        }
    }
    initPropertySources();
}
  1. 初始化器
private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() {
    return this::selfInitialize;
}

private void selfInitialize(ServletContext servletContext) throws ServletException {
    prepareWebApplicationContext(servletContext);
    registerApplicationScope(servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
    //遍历获取到的初始化器,并启动
    for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
        beans.onStartup(servletContext);
    }
}
  1. 获取了哪些初始化器
protected Collection<ServletContextInitializer> getServletContextInitializerBeans() {
		return new ServletContextInitializerBeans(getBeanFactory());
}

@SafeVarargs
public ServletContextInitializerBeans(ListableBeanFactory beanFactory,
		Class<? extends ServletContextInitializer>... initializerTypes) {
	this.initializers = new LinkedMultiValueMap<>();
	this.initializerTypes = (initializerTypes.length != 0) ? Arrays.asList(initializerTypes)
			: Collections.singletonList(ServletContextInitializer.class);
	addServletContextInitializerBeans(beanFactory);
	addAdaptableBeans(beanFactory);
	List<ServletContextInitializer> sortedInitializers = this.initializers.values().stream()
			.flatMap((value) -> value.stream().sorted(AnnotationAwareOrderComparator.INSTANCE))
			.collect(Collectors.toList());
	this.sortedList = Collections.unmodifiableList(sortedInitializers);
	logMappings(this.initializers);
}

protected void addAdaptableBeans(ListableBeanFactory beanFactory) {
    MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory);
    addAsRegistrationBean(beanFactory, Servlet.class, new ServletRegistrationBeanAdapter(multipartConfig));
    addAsRegistrationBean(beanFactory, Filter.class, new FilterRegistrationBeanAdapter());
    //通过ServletListenerRegistrationBean.getSupportedTypes()获取
    for (Class<?> listenerType : ServletListenerRegistrationBean.getSupportedTypes()) {
        addAsRegistrationBean(beanFactory, EventListener.class, (Class<EventListener>) listenerType,
                              new ServletListenerRegistrationBeanAdapter());
    }
}

private static final Set<Class<?>> SUPPORTED_TYPES;
static {
    Set<Class<?>> types = new HashSet<>();
    types.add(ServletContextAttributeListener.class);
    types.add(ServletRequestListener.class);
    types.add(ServletRequestAttributeListener.class);
    types.add(HttpSessionAttributeListener.class);
    types.add(HttpSessionListener.class);
    types.add(ServletContextListener.class);
    SUPPORTED_TYPES = Collections.unmodifiableSet(types);
}
posted @ 2020-07-31 14:08  莫伊u  阅读(341)  评论(0)    收藏  举报