Springmvc from entry to source code analysis topic 2_tomcat how to load ContextLoaderListener during service startup

Return to the topic list

Springmvc from entry to source code analysis topic 2_tomcat how to load ContextLoaderListener during service startup

Preface

In the previous article, we made relevant preliminary preparations, and set up our project environment, and successfully ran our first springmvc project helloword, but we did not elaborate and analyze the configuration in our configuration file. In this article and subsequent articles, we will analyze and explain the role of these configurations, and dive into the source code to explain how these configurations are implemented.

The role of ServletContext

  • ServletContextLet me talk about the role first , because it org.springframework.web.context.ContextLoaderListeneris very important for our analysis later .

  • ServletContext is a global storage space for information. When the server starts, it exists, and when the server is shut down, it is released. Request, a user can have multiple; session, one user; and servletContext, all users share one. Therefore, in order to save space and improve efficiency, in ServletContext, it is necessary to put some information that is necessary, important, and shared by all users and is safe.

  • After starting the web container, the web container will read the configuration information in web.xml and supplement the ServletContext. (Note: The configuration loading sequence is: context-param -> listener -> filter -> servlet)

The role of ServletContextListener

ServletContextListener is a listener of ServletContext, an interface used to receive notification events about ServletContext life cycle changes. Monitor ServletContext changes. For example, ServletContext is created when the server starts, and ServletContext is destroyed when the server is shut down.

Source code analysis of ContextLoaderListener

  • First, let's take a look at how to configure in web.xmlorg.springframework.web.context.ContextLoaderListener
<!-- 使用ContextLoaderListener配置时,需要告诉它Spring配置文件的位置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!-- 
	     配置上下文载入器,上下文载入器载入除DispatherServlet载入的配置文件之外的其他上下文配置文件
	  最常用的上下文载入器是一个Servlet监听器,器名称为ContextLoaderListener
	 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
  • Source code of ContextLoaderListener
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
	private ContextLoader contextLoader;
	...
	/**
	 * Initialize the root web application context.
	 */
	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	protected ContextLoader createContextLoader() {
		return null;
	}
	...
}
  • From the ContextLoaderListenersource, we see that it implements ServletContextListeneran interface, then the process started by the container is bound to call ContextLoaderListener#contextInitialized(...)a method, called when the container is closed ContextLoaderListener#contextDestroyed(...)method

  • So what ContextLoaderListener#contextInitialized(...)is the main function of the method? Its main function is initialization WebApplicationContext. initWebApplicationContext(...)You can see from the comment of the method called in the method, how is it done? Let's continue to look down

  • ContextLoader#initWebApplicationContext(...)Code snippet

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
	if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
		throw new IllegalStateException(
				"Cannot initialize context because there is already a root application context present - " +
				"check whether you have multiple ContextLoader* definitions in your web.xml!");
	}
	...
	try {
		// Store context in local instance variable, to guarantee that
		// it is available on ServletContext shutdown.
		if (this.context == null) {
			this.context = createWebApplicationContext(servletContext);
		}
		...
		// 配置并刷新WebApplicationContext
		ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
		configureAndRefreshWebApplicationContext(cwac, servletContext);
		...
		servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
		...
		return this.context;
	}catch (RuntimeException ex) {
	...
}
  • ContextLoader#createWebApplicationContext(...)Code snippet
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
	//获取 org.springframework.web.context.support.XmlWebApplicationContext 的class
	Class<?> contextClass = determineContextClass(sc);
	...
	//通过反射创建WebApplicationContext对象
	return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}
  • In ContextLoader#initWebApplicationContext(...), first determine whether it exists in the servletContext, if it exists WebApplicationContext, throw an exception, and then determine whether the object is empty. When the program is executed for the first time, the object is empty, then call to ContextLoader#createWebApplicationContext(...)create the WebApplicationContextobject, and then call the ContextLoader#configureAndRefreshWebApplicationContext(...)method configuration And refresh the WebApplicationContext context

  • ContextLoader#configureAndRefreshWebApplicationContext(...)Method code snippet

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
	...
	//将ServletContext对象保存到上下文中
	wac.setServletContext(sc);
	//获取web.xml中配置的contextConfigLocation的值
	String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
	if (configLocationParam != null) {
		wac.setConfigLocation(configLocationParam);
	}
	....
	// 刷新WebApplicationContext上下文
	wac.refresh();
}
  • The next step is the WebApplicationContextobject is set to servletContextthe easy later use, this is the org.springframework.web.context.ContextLoaderListenerrole of

to sum up

Through the above analysis, it is not difficult to see that org.springframework.web.context.ContextLoaderListenerthe role is to load contextConfigLocationthe spring bean configuration file that we specified in web.xml to create the root WebApplicationContext context. Ok, this article is here, the next one we will analyze the container startup org.springframework.web.servlet.DispatcherServletHow is the process executed

Return to the topic list

Guess you like

Origin blog.csdn.net/u013328649/article/details/111628687