`
Silmon
  • 浏览: 54528 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Spring配置文件加载流程

阅读更多

Spring配置文件是集成了Spring框架的项目的核心,引擎从哪里开始,中间都执行了哪些操作,小谈一下它的执行流程。

容器先是加载web.xml

 

接着是applicationContext.xml在web.xml里的注册

 

一种方法是加入ContextLoaderServlet这个servlet

<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext.xml</param-value>
	</context-param>
     <servlet>
		<servlet-name>context</servlet-name>
		<servlet-class>
			org.springframework.web.context.ContextLoaderServlet
		</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>

还有一种是添加ContextLoaderListener这个监听器

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 

 

下面是ContextLoaderServlet源代码

package org.springframework.web.context;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ContextLoaderServlet extends HttpServlet {

	private ContextLoader contextLoader;


	/**
	 * Initialize the root web application context.
	 */

public void init() throws ServletException {
		this.contextLoader = createContextLoader();
		this.contextLoader.initWebApplicationContext(getServletContext());
	}	/**
	 * Create the ContextLoader to use. Can be overridden in subclasses.
	 * @return the new ContextLoader
	 */
	protected ContextLoader createContextLoader() {
		return new ContextLoader();
	}

	/**
	 * Return the ContextLoader used by this servlet. 
	 * @return the current ContextLoader
	 */
	public ContextLoader getContextLoader() {
		return this.contextLoader;
	}


	/**
	 * Close the root web application context.
	 */
	public void destroy() {
		if (this.contextLoader != null) {
			this.contextLoader.closeWebApplicationContext(getServletContext());
		}
	}


	/**
	 * This should never even be called since no mapping to this servlet should
	 * ever be created in web.xml. That's why a correctly invoked Servlet 2.3
	 * listener is much more appropriate for initialization work ;-)
	 */
	public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
		getServletContext().log(
				"Attempt to call service method on ContextLoaderServlet as [" +
				request.getRequestURI() + "] was ignored");
		response.sendError(HttpServletResponse.SC_BAD_REQUEST);
	}


	public String getServletInfo() {
		return "ContextLoaderServlet for Servlet API 2.3 " +
		    "(deprecated in favor of ContextLoaderListener for Servlet API 2.4)";
	}

}
 

ContextLoaderListener源代码

package org.springframework.web.context;

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

public class ContextLoaderListener implements ServletContextListener {

	private ContextLoader contextLoader;


	/**
	 * Initialize the root web application context.
	 */
	public void contextInitialized(ServletContextEvent event) {
               this.contextLoader = createContextLoader();
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	/**
	 * Create the ContextLoader to use. Can be overridden in subclasses.
	 * @return the new ContextLoader
	 */
	protected ContextLoader createContextLoader() {
		return new ContextLoader();
	}

	/**
	 * Return the ContextLoader used by this listener.
	 * @return the current ContextLoader
	 */
	public ContextLoader getContextLoader() {
		return this.contextLoader;
	}


	/**
	 * Close the root web application context.
	 */
	public void contextDestroyed(ServletContextEvent event) {
		if (this.contextLoader != null) {
			this.contextLoader.closeWebApplicationContext(event.getServletContext());
		}
	}

}

 以上都提到了ContextLoader这个类

package org.springframework.web.context;

public class ContextLoader {

	public static final String CONTEXT_CLASS_PARAM = "contextClass";

	public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";

       public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";

	public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";

	private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties";


	private static final Properties defaultStrategies;

	static {
				try {
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
		}
	}


	private static final Log logger = LogFactory.getLog(ContextLoader.class);

	private static final Map currentContextPerThread = CollectionFactory.createConcurrentMapIfPossible(1);

	private WebApplicationContext context;

	private BeanFactoryReference parentContextRef;

	public WebApplicationContext initWebApplicationContext(ServletContext servletContext)

          throws IllegalStateException, BeansException {

		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!");
		}

		servletContext.log("Initializing Spring root WebApplicationContext");
		if (logger.isInfoEnabled()) {
			logger.info("Root WebApplicationContext: initialization started");
		}
		long startTime = System.currentTimeMillis();

		try {
			// Determine parent for root web application context, if any.
			ApplicationContext parent = loadParentContext(servletContext);

			// Store context in local instance variable, to guarantee that
			// it is available on ServletContext shutdown.
			this.context = createWebApplicationContext(servletContext, parent);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
			currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this.context);

			if (logger.isDebugEnabled()) {
				logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
						WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
			}
			if (logger.isInfoEnabled()) {
				long elapsedTime = System.currentTimeMillis() - startTime;
				logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
			}

			return this.context;
		}
		catch (RuntimeException ex) {
			logger.error("Context initialization failed", ex);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
			throw ex;
		}
		catch (Error err) {
			logger.error("Context initialization failed", err);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
			throw err;
		}
	}

	protected WebApplicationContext createWebApplicationContext(
			ServletContext servletContext, ApplicationContext parent) throws BeansException {

		Class contextClass = determineContextClass(servletContext);
		if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
			throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
					"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
		}

		ConfigurableWebApplicationContext wac =
				(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
		wac.setParent(parent);
		wac.setServletContext(servletContext);
		wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));






customizeContext(servletContext, wac);
		wac.refresh();

		return wac;
	}

		protected Class determineContextClass(ServletContext servletContext) throws ApplicationContextException {
		String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
		if (contextClassName != null) {
			try {
				return ClassUtils.forName(contextClassName);
			}
			catch (ClassNotFoundException ex) {
				throw new ApplicationContextException(
						"Failed to load custom context class [" + contextClassName + "]", ex);
			}
		}
		else {
			contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
			try {
				return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
			}
			catch (ClassNotFoundException ex) {
				throw new ApplicationContextException(
						"Failed to load default context class [" + contextClassName + "]", ex);
			}
		}
	}

		protected void customizeContext(
			ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {
	}

	protected ApplicationContext loadParentContext(ServletContext servletContext)
			throws BeansException {

		ApplicationContext parentContext = null;
		String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
		String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);

		if (parentContextKey != null) {
			// locatorFactorySelector may be null, indicating the default "classpath*:beanRefContext.xml"
			BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
			if (logger.isDebugEnabled()) {
				logger.debug("Getting parent context definition: using parent context key of '" +
						parentContextKey + "' with BeanFactoryLocator");
			}
			this.parentContextRef = locator.useBeanFactory(parentContextKey);
			parentContext = (ApplicationContext) this.parentContextRef.getFactory();
		}

		return parentContext;
	}

	public void closeWebApplicationContext(ServletContext servletContext) {
		servletContext.log("Closing Spring root WebApplicationContext");
		try {
			if (this.context instanceof ConfigurableWebApplicationContext) {
				((ConfigurableWebApplicationContext) this.context).close();
			}
		}
		finally {
			currentContextPerThread.remove(Thread.currentThread().getContextClassLoader());
			servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
			if (this.parentContextRef != null) {
				this.parentContextRef.release();
			}
		}
	}


	public static WebApplicationContext getCurrentWebApplicationContext() {
		return (WebApplicationContext) currentContextPerThread.get(Thread.currentThread().getContextClassLoader());
	}

}

  ContextLoaderServlet和ContextLoaderListener都是先创建ContextLoader的一个对象,然后调用它的initWebApplicationContex方法初始化WebApplicationContext获得一个对象;

 

分享到:
评论

相关推荐

    spring配置文件加密实现

    为了保护这些敏感信息不被非法访问或篡改,我们可以对Spring配置文件进行加密处理。本文将深入探讨如何在Java环境中,利用TE网络技术实现Spring配置文件的加密。 首先,我们需要理解Spring配置文件的基本结构。...

    Spring IoC加载流程讲解

    在 loadBeanDefinitions() 方法中,我们使用 XmlBeanDefinitionReader 将配置文件加载到 DefaultListableBeanFactory 中。DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口,将该接口传入 ...

    Spring配置文件集合

    通过这些配置文件的组合,我们可以构建出一个完整的Spring驱动的JavaWeb应用,涵盖了从数据访问到业务逻辑,再到用户界面的完整流程。Spring的这些配置文件使得我们可以模块化、解耦合地管理应用组件,提高了代码的...

    spring mvc的配置文件详解

    DispatcherServlet 加载时,Spring 会尝试读取相关的配置文件。默认情况下,这些配置文件位于 web.xml 相同的路径下,并且文件名与注册的 Servlet 名相关联,即 `&lt;servlet-name&gt;-servlet.xml`。例如,在本例中,默认...

    Spring读取配置文件原理(Spring如何依赖注入的)

    1. 加载XML文件:通过`Resource`接口加载指定的XML配置文件,`ClassPathResource`是常用的实现类,可以从类路径中加载资源。 2. 解析XML:使用`DocumentBuilder`解析XML文档,获取DOM树。 3. 遍历DOM树:`...

    SpringMVC一些配置文件的demo

    在"SpringMVC一些配置文件的demo"中,我们可以深入理解SpringMVC的核心配置和工作流程。 1. **核心配置文件**:SpringMVC的配置通常在`dispatcher-servlet.xml`中进行,这是SpringMVC的前端控制器DispatcherServlet...

    java中的@Value获取不到配置文件的值,也加载不到默认值

    自己开发一个工具类,为第三方应用提供调用接口,但是打包后测试过程中,发现了一个问题就是在用@Value获取配置文件内容的时候,无法获取我们的配置信息,也无法加载我们配置的默认值!具体配置如下: @Value("${...

    spring配置步骤

    ### Spring配置步骤详解 #### 一、Spring框架简介 Spring框架是Java平台上的一个开源框架,它提供了一种简化企业级应用开发的方式。Spring的核心功能包括依赖注入(Dependency Injection, DI)、面向切面编程...

    Spring框架的流程

    2. **核心配置文件**:`applicationContext.xml`是Spring应用的核心配置文件,它定义了所有Bean的配置信息,包括Bean的创建、依赖关系以及行为。这个文件是Spring容器读取的入口,通过它可以管理所有的Bean实例。 3...

    spring加载

    1. **配置文件解析**:Spring的启动通常始于一个或多个配置文件,如XML或Java配置类。这些配置文件定义了bean的定义,包括bean的类型、属性、依赖关系等。Spring通过BeanDefinitionReader读取这些配置,将其转化为...

    Hibernate 和 Spring的结合配置文件

    同时,`Spring`的配置文件(如`applicationContext.xml`)中会包含`Hibernate`的相关bean定义,如SessionFactory、DataSource、TransactionManager等,实现对`Hibernate`的管理。 接着,`HQL`是`Hibernate`提供的...

    struts2+hibenate+spring的配置文件

    然后,`applicationContext.xml`是Spring的配置文件,它定义了Bean的实例化、依赖注入、事务管理等。在SSH集成中,Spring作为IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)容器,...

    struct2.3+spring3.1+mybits3.1 核心Jar包和配置文件

    `struts.xml`是Struts2的核心配置文件,它定义了动作映射、结果类型和全局拦截器等,使得开发者能够控制应用程序的行为和流程。 Spring3.1是另一个关键组件,它是一个全面的企业级应用开发框架,提供依赖注入(DI)...

    在Spring Boot中加载XML配置的完整步骤

    理解`@ImportResource`注解,它实际上是在Spring的`spring-context`模块中定义的,用于在Spring容器启动时加载XML配置文件。`ImportResource`内部实现了`BeanDefinitionReader`接口,该接口负责读取XML文件并将其...

    springcloud config配置中心

    1. **配置存储**:所有的配置文件都存储在一个集中式版本控制系统(如Git)中,每个环境有自己的分支。 2. **Config Server 启动**:启动时,Config Server 会拉取Git仓库中的所有配置信息。 3. **客户端注册**:...

    ssm配置文件.zip

    - `spring.xml`:这是Spring的核心配置文件,定义了Bean的声明、依赖注入等。在这个文件中,我们可以配置数据源、事务管理器、DAO Bean以及Service Bean等。例如,为数据库连接配置DataSource,设置事务管理器(如...

    Spring+SpringMVC配置加载顺序1

    Spring 和 SpringMVC 的配置加载顺序是理解这两个框架协同工作的重要方面。...理解这些加载顺序和配置方式对于调试和优化Spring应用的性能至关重要,因为它们直接影响到Spring容器的初始化以及请求的处理流程。

    struts2,hibernate,spring整合源码,配置文件,jar包

    此外,事务管理也是重要的一步,通常在Spring配置文件中定义PlatformTransactionManager,确保在多数据库操作时的事务一致性。 在"web01Spring_Register008"这个文件名中,可能指的是一个注册功能相关的Web应用模块...

Global site tag (gtag.js) - Google Analytics