Spring源码分析-配置文件加载流程

Spring配置文件加载流程

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

容器先是加载web .xml

 

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

 

一种方法是加入ContextLoaderServlet这个servlet

Xml代码
  1. < context-param >   
  2.         < param-name > contextConfigLocation param-name >   
  3.         < param-value > /WEB -INF/applicationContext.xml param-value >   
  4.      context-param >   
  5.      < servlet >   
  6.         < servlet-name > context servlet-name >   
  7.         < servlet-class >   
  8.             org.springframework.web .context.ContextLoaderServlet  
  9.          servlet-class >   
  10.         < load-on-startup > 0 load-on-startup >   
  11.      servlet >   

		contextConfigLocation
		/WEB
-INF/applicationContext.xml
	
     
		context
		
			org.springframework.web
.context.ContextLoaderServlet
		
		0
	

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

Xml代码
  1. < context-param >   
  2.     < param-name > contextConfigLocation param-name >   
  3.     < param-value > /WEB -INF/applicationContext.xml param-value >   
  4. context-param >   
  5.   
  6. < listener >   
  7.     < listener-class > org.springframework.web .context.ContextLoaderListener listener-class >   
  8. listener >   

    contextConfigLocation
    /WEB
-INF/applicationContext.xml



    org.springframework.web
.context.ContextLoaderListener
 

 

下面是ContextLoaderServlet源代码

Java代码
  1. package  org.springframework.web .context;  
  2.   
  3. import  java.io.IOException;  
  4.   
  5. import  javax.servlet.ServletException;  
  6. import  javax.servlet.http.HttpServlet;  
  7. import  javax.servlet.http.HttpServletRequest;  
  8. import  javax.servlet.http.HttpServletResponse;  
  9.   
  10. public   class  ContextLoaderServlet  extends  HttpServlet {  
  11.   
  12.     private  ContextLoader  contextLoader ;  
  13.   
  14.   
  15.     /**  
  16.      * Initialize the root web  application context.  
  17.      */   
  18.   
  19. public   void  init()  throws  ServletException {  
  20.         this .contextLoader  = createContextLoader();  
  21.         this .contextLoader .initWebApplicationContext(getServletContext());  
  22.     }   /**  
  23.      * Create the ContextLoader  to use. Can be overridden in  subclasses.  
  24.      * @return the new ContextLoader  
  25.      */   
  26.     protected  ContextLoader  createContextLoader() {  
  27.         return   new  ContextLoader ();  
  28.     }  
  29.   
  30.     /**  
  31.      * Return the ContextLoader  used by this servlet.   
  32.      * @return the current ContextLoader  
  33.      */   
  34.     public  ContextLoader  getContextLoader() {  
  35.         return   this .contextLoader ;  
  36.     }  
  37.   
  38.   
  39.     /**  
  40.      * Close the root web  application context.  
  41.      */   
  42.     public   void  destroy() {  
  43.         if  ( this .contextLoader  !=  null ) {  
  44.             this .contextLoader .closeWebApplicationContext(getServletContext());  
  45.         }  
  46.     }  
  47.   
  48.   
  49.     /**  
  50.      * This should never even be called since no mapping to this servlet should  
  51.      * ever be created in  web .xml. That's why a correctly invoked Servlet 2.3  
  52.      * listener is much more appropriate for initialization work ;-)  
  53.      */   
  54.     public   void  service(HttpServletRequest request, HttpServletResponse response)  throws  IOException {  
  55.         getServletContext().log(  
  56.                 "Attempt to call service method on ContextLoaderServlet as ["  +  
  57.                 request.getRequestURI() + "] was ignored" );  
  58.         response.sendError(HttpServletResponse.SC_BAD_REQUEST);  
  59.     }  
  60.   
  61.   
  62.     public  String getServletInfo() {  
  63.         return   "ContextLoaderServlet for Servlet API 2.3 "  +  
  64.             "(deprecated in  favor of ContextLoaderListener for Servlet API 2.4)" ;  
  65.     }  
  66.   
  67. }  
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源代码

Java代码
  1. package  org.springframework.web .context;  
  2.   
  3. import  javax.servlet.ServletContextEvent;  
  4. import  javax.servlet.ServletContextListener;  
  5.   
  6. public   class  ContextLoaderListener  implements  ServletContextListener {  
  7.   
  8.     private  ContextLoader  contextLoader ;  
  9.   
  10.   
  11.     /**  
  12.      * Initialize the root web  application context.  
  13.      */   
  14.     public   void  contextInitialized(ServletContextEvent event) {  
  15.                this .contextLoader  = createContextLoader();  
  16.         this .contextLoader .initWebApplicationContext(event.getServletContext());  
  17.     }  
  18.   
  19.     /**  
  20.      * Create the ContextLoader  to use. Can be overridden in  subclasses.  
  21.      * @return the new ContextLoader  
  22.      */   
  23.     protected  ContextLoader  createContextLoader() {  
  24.         return   new  ContextLoader ();  
  25.     }  
  26.   
  27.     /**  
  28.      * Return the ContextLoader  used by this listener.  
  29.      * @return the current ContextLoader  
  30.      */   
  31.     public  ContextLoader  getContextLoader() {  
  32.         return   this .contextLoader ;  
  33.     }  
  34.   
  35.   
  36.     /**  
  37.      * Close the root web  application context.  
  38.      */   
  39.     public   void  contextDestroyed(ServletContextEvent event) {  
  40.         if  ( this .contextLoader  !=  null ) {  
  41.             this .contextLoader .closeWebApplicationContext(event.getServletContext());  
  42.         }  
  43.     }  
  44.   
  45. }  
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 这个类

Java代码
  1. package  org.springframework.web .context;  
  2.   
  3. public   class  ContextLoader  {  
  4.   
  5.     public   static   final  String CONTEXT_CLASS_PARAM =  "contextClass" ;  
  6.   
  7.     public   static   final  String CONFIG_LOCATION_PARAM =  "contextConfigLocation" ;  
  8.   
  9.        public   static   final  String LOCATOR_FACTORY_SELECTOR_PARAM =  "locatorFactorySelector" ;  
  10.   
  11.     public   static   final  String LOCATOR_FACTORY_KEY_PARAM =  "parentContextKey" ;  
  12.   
  13.     private   static   final  String DEFAULT_STRATEGIES_PATH =  "ContextLoader .properties" ;  
  14.   
  15.   
  16.     private   static   final  Properties defaultStrategies;  
  17.   
  18.     static  {  
  19.                 try  {  
  20.             ClassPathResource resource = new  ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader . class );  
  21.             defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);  
  22.         }  
  23.         catch  (IOException ex) {  
  24.             throw   new  IllegalStateException( "Could not load 'ContextLoader .properties': "  + ex.getMessage());  
  25.         }  
  26.     }  
  27.   
  28.   
  29.     private   static   final  Log logger = LogFactory.getLog(ContextLoader . class );  
  30.   
  31.     private   static   final  Map currentContextPerThread = CollectionFactory.createConcurrentMapIfPossible( 1 );  
  32.   
  33.     private  WebApplicationContext context;  
  34.   
  35.     private  BeanFactoryReference parentContextRef;  
  36.   
  37.     public  WebApplicationContext initWebApplicationContext(ServletContext servletContext)  
  38.   
  39.           throws  IllegalStateException, BeansException {  
  40.   
  41.         if  (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) !=  null ) {  
  42.             throw   new  IllegalStateException(  
  43.                     "Cannot initialize context because there is already a root application context present - "  +  
  44.                     "check  whether  you  have  multiple  ContextLoaderdefinitions  in  your  web .xml!" );  
  45.         }  
  46.   
  47.         servletContext.log("Initializing Spring root WebApplicationContext" );  
  48.         if  (logger.isInfoEnabled()) {  
  49.             logger.info("Root WebApplicationContext: initialization started" );  
  50.         }  
  51.         long  startTime = System.currentTimeMillis();  
  52.   
  53.         try  {  
  54.             // Determine parent for root web  application context, if any.   
  55.             ApplicationContext parent = loadParentContext(servletContext);  
  56.   
  57.             // Store context in  local instance variable, to guarantee that   
  58.             // it is available on ServletContext shutdown.   
  59.             this .context = createWebApplicationContext(servletContext, parent);  
  60.             servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this .context);  
  61.             currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this .context);  
  62.   
  63.             if  (logger.isDebugEnabled()) {  
  64.                 logger.debug("Published root WebApplicationContext as ServletContext attribute with name ["  +  
  65.                         WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]" );  
  66.             }  
  67.             if  (logger.isInfoEnabled()) {  
  68.                 long  elapsedTime = System.currentTimeMillis() - startTime;  
  69.                 logger.info("Root WebApplicationContext: initialization completed in  "  + elapsedTime +  " ms" );  
  70.             }  
  71.   
  72.             return   this .context;  
  73.         }  
  74.         catch  (RuntimeException ex) {  
  75.             logger.error("Context initialization failed" , ex);  
  76.             servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);  
  77.             throw  ex;  
  78.         }  
  79.         catch  (Error err) {  
  80.             logger.error("Context initialization failed" , err);  
  81.             servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);  
  82.             throw  err;  
  83.         }  
  84.     }  
  85.   
  86.     protected  WebApplicationContext createWebApplicationContext(  
  87.             ServletContext servletContext, ApplicationContext parent) throws  BeansException {  
  88.   
  89.         Class contextClass = determineContextClass(servletContext);  
  90.         if  (!ConfigurableWebApplicationContext. class .isAssignableFrom(contextClass)) {  
  91.             throw   new  ApplicationContextException( "Custom context class ["  + contextClass.getName() +  
  92.                     "] is not of type ["  + ConfigurableWebApplicationContext. class .getName() +  "]" );  
  93.         }  
  94.   
  95.         ConfigurableWebApplicationContext wac =  
  96.                 (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);  
  97.         wac.setParent(parent);  
  98.         wac.setServletContext(servletContext);  
  99.         "color: rgb(0, 0, 0);" >wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));  
  100.   
  101.   
  102.   
  103.   
  104.   
  105.   
  106. customizeContext(servletContext, wac);  
  107.         wac.refresh();  
  108.   
  109.         return  wac;  
  110.     }  
  111.   
  112.         protected  Class determineContextClass(ServletContext servletContext)  throws  ApplicationContextException {  
  113.         String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);  
  114.         if  (contextClassName !=  null ) {  
  115.             try  {  
  116.                 return  ClassUtils.forName(contextClassName);  
  117.             }  
  118.             catch  (ClassNotFoundException ex) {  
  119.                 throw   new  ApplicationContextException(  
  120.                         "Failed to load custom context class ["  + contextClassName +  "]" , ex);  
  121.             }  
  122.         }  
  123.         else  {  
  124.             contextClassName = defaultStrategies.getProperty(WebApplicationContext.class .getName());  
  125.             try  {  
  126.                 return  ClassUtils.forName(contextClassName, ContextLoader . class .getClassLoader());  
  127.             }  
  128.             catch  (ClassNotFoundException ex) {  
  129.                 throw   new  ApplicationContextException(  
  130.                         "Failed to load default context class ["  + contextClassName +  "]" , ex);  
  131.             }  
  132.         }  
  133.     }  
  134.   
  135.         protected   void  customizeContext(  
  136.             ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {  
  137.     }  
  138.   
  139.     protected  ApplicationContext loadParentContext(ServletContext servletContext)  
  140.             throws  BeansException {  
  141.   
  142.         ApplicationContext parentContext = null ;  
  143.         String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);  
  144.         String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);  
  145.   
  146.         if  (parentContextKey !=  null ) {  
  147.             // locatorFactorySelector may be null, indicating the default "classpath*:beanRefContext.xml"   
  148.             BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);  
  149.             if  (logger.isDebugEnabled()) {  
  150.                 logger.debug("Getting parent context definition: using parent context key of '"  +  
  151.                         parentContextKey + "' with BeanFactoryLocator" );  
  152.             }  
  153.             this .parentContextRef = locator.useBeanFactory(parentContextKey);  
  154.             parentContext = (ApplicationContext) this .parentContextRef.getFactory();  
  155.         }  
  156.   
  157.         return  parentContext;  
  158.     }  
  159.   
  160.     public   void  closeWebApplicationContext(ServletContext servletContext) {  
  161.         servletContext.log("Closing Spring root WebApplicationContext" );  
  162.         try  {  
  163.             if  ( this .context  instanceof  ConfigurableWebApplicationContext) {  
  164.                 ((ConfigurableWebApplicationContext) this .context).close();  
  165.             }  
  166.         }  
  167.         finally  {  
  168.             currentContextPerThread.remove(Thread.currentThread().getContextClassLoader());  
  169.             servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);  
  170.             if  ( this .parentContextRef !=  null ) {  
  171.                 this .parentContextRef.release();  
  172.             }  
  173.         }  
  174.     }  
  175.   
  176.   
  177.     public   static  WebApplicationContext getCurrentWebApplicationContext() {  
  178.         return  (WebApplicationContext) currentContextPerThread.get(Thread.currentThread().getContextClassLoader());  
  179.     }  
  180.   
  181. }  
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)

你可能感兴趣的:(JAVA-EE-Spring)