Spring初始化Bean

 在web.xml 配置

 <context-param>

       <param-name>contextConfigLocation</param-name>   

  <param-value>classpath:applicationContext.xml</param-value>  

</context-param>

 <listener>

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

  </listener>

 org.springframework.web.context.ContextLoaderListener继承自org.springframework.web.context.ContextLoader,同时实现了javax.servlet.ServletContextListener接口,

在系统启动的时候,首先会调用ContextLoaderListener方法中的public void contextInitialized(ServletContextEvent event)方法,该方法源代码如下所示:

 private ContextLoader contextLoader;

 public void contextInitialized(ServletContextEvent event) {

    this.contextLoader = createContextLoader();   

    if (this.contextLoader == null) {           

      this.contextLoader = this;      

       } 

    this.contextLoader.initWebApplicationContext(event.getServletContext());  

}

 第一步是创建一个ContextLoader,通过查看源代码知道,该方法createContextLoader()是个Deprecated的方法,这一步返回值为null。最重要的是这最后一步:  this.contextLoader.initWebApplicationContext(event.getServletContext()); 

 该方法通过web.xml配置文件中contextClass参数和contextConfigLocation的值来初始化给定的ServletContext。

 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;   }  }  

 

 先跳过第一步  ApplicationContext parent = loadParentContext(servletContext);   该方法以判断ApplicationContext parent是否存在

 最重要关心第二步  this.context = createWebApplicationContext(servletContext, parent);  createWebApplicationContext源代码:    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);  

 //保持对父上下文和ServletContext引用到根上下文

 wac.setParent(parent);  

 wac.setServletContext(servletContext);  

 //web.xml中取得相关参数初始化

 wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));   

 customizeContext(servletContext, wac);  

//对WebApplistcationContext进行初始化

 wac.refresh();

  return wac;  

}

 org.springframework.web.context.ConfigurableWebApplicationContext接口,

 该接口继承自org.springframework.web.context.WebApplicationContext和org.springframework.context.ConfigurableApplicationContext接口。

 系统所做的是实例化org.springframework.web.context.support.XmlWebApplicationContext,并进行一些属性的设置。之后,整个启动过程也就完成了

posted @ 2013-11-27 15:27  Believemyself  阅读(251)  评论(0)    收藏  举报