Spring初始化 - ContextLoaderListener

一.概述

ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

二.初始化

1.配置

在web.xml中配置如下,则web容器启动时会触发监听器ContextLoaderListener
<listener>    
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    
  </listener>  

2.ContextLoaderListener实例化

ContextLoaderListener类实现了 ServletContextListener接口,继承了ContextLoder类,并且持有一个ContextLoder实例对象,ContextLoader主要处理XmlWebApplicationContext的创建。
当web容器启动时触发监听器,ContextLoaderListener调用无参构造函数实例化。

3.启动

接口ServletContextListener的contextInitialized(ServletContextEvent paramServletContextEvent)方法初始化上下文ContextLoaderListener实现了contextInitialized方法。
所以监听器被触发后,会调用此方法
	/**
	 * Initialize the root web application context.
	 */
	public void contextInitialized(ServletContextEvent event) {
		// createContextLoader()返回null
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			// 为持有的ContextLoader实例赋值
			this.contextLoader = this;
		}
		// ContextLoader实例对象实例化上下文
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	@Deprecated 废弃
	protected ContextLoader createContextLoader() {
		return null;
	}

4.下一篇

详情请看下一篇: Spring初始化 - ContextLoader

三.无注释源码

package org.springframework.web.context;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {

	private ContextLoader contextLoader;

	public ContextLoaderListener() {
	}

	public ContextLoaderListener(WebApplicationContext context) {
		super(context);
	}

	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	// 废弃
	@Deprecated
	protected ContextLoader createContextLoader() {
		return null;
	}

	// 废弃
	@Deprecated
	public ContextLoader getContextLoader() {
		return this.contextLoader;
	}

	public void contextDestroyed(ServletContextEvent event) {
		if (this.contextLoader != null) {
			this.contextLoader.closeWebApplicationContext(event.getServletContext());
		}
		ContextCleanupListener.cleanupAttributes(event.getServletContext());
	}

}

四.注释源码

package org.springframework.web.context;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * 监听Spring的根(WebApplicationContext)的启动和销毁
 *
 * 1.如果在web.xml中存在org.springframework.web.util.Log4jConfigListener的监听器
 * 	 本监听器需要在其后注册才能起效
 *
 * 2.从Spring 3.1起,ContextLoaderListener支持通过{@link #ContextLoaderListener(WebApplicationContext)}构造函数
 *   注入根Web应用程序上下文,允许在Servlet 3.0+环境中进行编程配置。 
 *   看{@link org.springframework.web.WebApplicationInitializer}使用示例。
 */
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
	// 实现Spring的初始化
	private ContextLoader contextLoader;


	/**
	 * 1. 创建一个新的ContextLoaderListener,他将基于servlet参数"contextClass"和"contextConfigLocation"
	 *    创建一个web应用程序上下文
	 *    有关每个的默认值的详细信息,请参阅{@link ContextLoader}类文档
	 *
	 * 2. 在web.xml中声明ContextLoaderListener为监听器时,需要无参构造函数,这个构造函数通常就会被用到
	 * 
	 * 3. 创建的应用程序上下文将被注册到ServletContext下
	 *    属性名WebApplicationContext.java#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
	 *
	 * 4.当此监听器调用{@link #contextDestroyed}方法时,Spring应用程序上下文将关闭
	 */
	public ContextLoaderListener() {
	}

	/**
	 * 1. 使用给定的应用程序上下文context创建一个新的ContextLoaderListener。
	 *    这个构造函数在Servlet 3.0+环境中很有用,通过{@link javax.servlet.ServletContext#addListener}可以注册监听器
	 * 
	 * 2.这个上下文context可能已经或者还没有刷新:org.springframework.context.ConfigurableApplicationContext#refresh()
	 *   如果上下文context是ConfigurableWebApplicationContext的实现,并且还没有刷新(推荐的方式)
	 *   会有以下情况:
	 *   (1)如果给定上下文context还没有分配id:org.springframework.context.ConfigurableApplicationContext#setId
	 *        会给他分配一个id
	 *   (2)ServletContext和ServletConfig对象将被委派给上下文对象context
	 *   (3)org.springframework.web.context.ContextLoader#customizeContext将被调用
	 *   (4)任何org.springframework.context.ApplicationContextInitializer将通过初试参数"contextInitializerClasses"指定
	 *   (5)org.springframework.context.ConfigurableApplicationContext#refresh将被调用
	 *   
	 * 3.如果上下文content已经刷新或不是ConfigurableWebApplicationContext的实现,
	 *   上述任何一种都不会在用户根据自己的具体需求执行这些操作(或不执行)的假设下进行
	 *
	 * 4.有关使用示例,请参阅{@link org.springframework.web.WebApplicationInitializer}
	 *
	 * 5.无论如何,给定的应用程序上下文content将被注册到ServletContext中,
	 *   属性名为WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE},
	 *  并且在此监听器调用{@link #contextDestroyed}方法时,Spring应用程序上下文将关闭。
	 */
	public ContextLoaderListener(WebApplicationContext context) {
		super(context);
	}

	/**
	 * 初始化web应用程序上下文的根
	 */
	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		// ContextLoader实现初始化
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	// 弃用
	@Deprecated
	protected ContextLoader createContextLoader() {
		return null;
	}

	// 弃用
	@Deprecated
	public ContextLoader getContextLoader() {
		return this.contextLoader;
	}


	/**
	 * 关闭应用程序的上下文
	 */
	public void contextDestroyed(ServletContextEvent event) {
		if (this.contextLoader != null) {
			this.contextLoader.closeWebApplicationContext(event.getServletContext());
		}
		ContextCleanupListener.cleanupAttributes(event.getServletContext());
	}

}

五.流程图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值