web服务器的启动流程与上下文创建

来源:互联网 发布:五笔 知乎 编辑:程序博客网 时间:2024/06/05 20:48

今天看Spring web源代码解析时发现,原来上下文是在加载web.xml的时候就会创建根上下文,究竟是怎样创建的呢,一开始我也不明白,但是看了web的启动流程后就明白了,那么下面我们先看看web服务器的启动流程

1.启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> 和 <context-param></context-param>

2.紧接着,容器创建一个ServletContext(上下文),这个WEB项目所有部分都将共享这个上下文.

3.容器将<context-param></context-param>转化为键值对,并交给ServletContext.

4.容器创建<listener></listener>中的类实例,即创建监听.

5.在监听中会有contextInitialized(ServletContextEvent args)初始化方法,在这个方法中获得
ServletContext = ServletContextEvent.getServletContext();
context-param的值 = ServletContext.getInitParameter("context-param的键");

6.得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早.
换句话说,这个时候,你对<context-param>中的键值做的操作,将在你的WEB项目完全启动之前被执行.

7.举例.你可能想在项目启动之前就打开数据库.
那么这里就可以在<context-param>中设置数据库的连接方式,在监听类中初始化数据库的连接.

8.这个监听是自己写的一个类,除了初始化方法,它还有销毁方法.用于关闭应用前释放资源.比如说数据库连接的关闭.

 

好,在web项目中使用过Spring框架的都知道,必须在web.xml中配置一个一:

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

代码:

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {

 private ContextLoader contextLoader;

public ContextLoaderListener() {
 }

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

 /**
  * 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());
 }

 /**
  * Create the ContextLoader to use. Can be overridden in subclasses.
  * @return the new ContextLoader
  * @deprecated in favor of simply subclassing ContextLoaderListener itself
  * (which extends ContextLoader, as of Spring 3.0)
  */
 @Deprecated
 protected ContextLoader createContextLoader() {
  return null;
 }

 /**
  * Return the ContextLoader used by this listener.
  * @return the current ContextLoader
  * @deprecated in favor of simply subclassing ContextLoaderListener itself
  * (which extends ContextLoader, as of Spring 3.0)
  */
 @Deprecated
 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());
  }
  ContextCleanupListener.cleanupAttributes(event.getServletContext());
 }

}

大家可以看到,这个类里面也有一个contextInitialized(ServletContextEvent args)初始化方法,方法里通过调用父类的方法:contextLoader.initWebApplicationContext(event.getServletContext());来创建Spring IOC容器的根上下文,具体怎么创建这里就不详述,有兴趣的可以去看一下Spring的源码解析。

其实我们如果自己写一些监听类,然后在web.xml里配置一下那么就可以在项目加载完成之前做好更多的初始化工作,但是如果设置得太多的,想必会影响项目加载速度,所以还是适当添加的好,如果有什么说得不对的地方,请多多指教