《How Tomcat Works》第六章:生命周期

一个完整的Web容器是由许多组件组成的,在容器启动时,这些组件必须全部要启动,并且初始化,当容器停止时,它们也要清除。(例如servlet要调用destory方法)保持组件启动和停止一致的机制就是通过LifeCycle接口来实现的。

    public static final String START_EVENT = "start";
    public static final String BEFORE_START_EVENT = "before_start";
    public static final String AFTER_START_EVENT = "after_start";
    public static final String STOP_EVENT = "stop";
    public static final String BEFORE_STOP_EVENT = "before_stop";
    public static final String AFTER_STOP_EVENT = "after_stop";

LifeCycle接口定义了这六个事件,根据字面意思可以看出,前三个是组件启动时发生的事件,后面三个是组件停止时发生的事件。LifeCycle接口中最重要的是start与stop方法,实现了这两个方法的组建类就可以被父组建启动和停止了,另外3个方法addLifecycleListener(),findLifecycleListeners(),和removeLifecycleListener()这三个方法和监听器相关,组件中可以具有对在该组件发生的事件感兴趣的监听器。当事件发生时,将会通知对该事件感兴趣的监听器。

那么组件的生命周期如何实现呢?我们具体来跟一下这个流程吧。

public synchronized void start() throws LifecycleException {
    if (started)
      throw new LifecycleException("SimpleContext has already started");

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
    started = true;
    try {
      // Start our subordinate components, if any
      if ((loader != null) && (loader instanceof Lifecycle))
        ((Lifecycle) loader).start();

      // Start our child containers, if any
      Container children[] = findChildren();
      for (int i = 0; i < children.length; i++) {
        if (children[i] instanceof Lifecycle)
          ((Lifecycle) children[i]).start();
      }

      // Start the Valves in our pipeline (including the basic),
      // if any
      if (pipeline instanceof Lifecycle)
        ((Lifecycle) pipeline).start();
      // Notify our interested LifecycleListeners
      lifecycle.fireLifecycleEvent(START_EVENT, null);
    }
    catch (Exception e) {
      e.printStackTrace();
    }

这是实现了Lifecycle接口的context类的start方法,首先LifecycleSupport类的实例lifecycle实例调用了fireLifecycleEvent方法,与“before-start-event”相关的事件就会发生,然后启动loader,启动所有组件,随后拿到所有的子容器,把他们都启动,再然后启动管道,激活所有的阀门,在调用了fireLifecycleEvent方法后,start方法也就结束了,至此,容器启动成功。

public void lifecycleEvent(LifecycleEvent event) {
    Lifecycle lifecycle = event.getLifecycle();
    System.out.println("SimpleContextLifecycleListener's event " +
      event.getType().toString());
    if (Lifecycle.START_EVENT.equals(event.getType())) {
      System.out.println("Starting context.");
    }
    else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
      System.out.println("Stopping context.");
    }
  }

这是监听器实现的lifecycleEvent方法。


public final class Bootstrap {
  public static void main(String[] args) {


    Wrapper wrapper1 = new SimpleWrapper();
    wrapper1.setName("Primitive");
    wrapper1.setServletClass("PrimitiveServlet");

    Wrapper wrapper2 = new SimpleWrapper();
    wrapper2.setName("Modern");
    wrapper2.setServletClass("ModernServlet");

    Context context = new SimpleContext();
    context.addChild(wrapper1);
    context.addChild(wrapper2);

    Mapper mapper = new SimpleContextMapper();
    mapper.setProtocol("http");
    context.addMapper(mapper);

    LifecycleListener listener = new SimpleContextLifecycleListener();
    ((Lifecycle) context).addLifecycleListener(listener);

    Loader loader = new SimpleLoader();
    context.setLoader(loader);


    // context.addServletMapping(pattern, name);
    context.addServletMapping("/Primitive", "Primitive");
    context.addServletMapping("/Modern", "Modern");

    Connector connector = new HttpConnector();

    connector.setContainer(context);
    try {
      connector.initialize();
      ((Lifecycle) connector).start();
      ((Lifecycle) context).start();

      // make the application wait until we press a key.
      System.in.read();
      ((Lifecycle) context).stop();
    }catch (Exception e) {
      e.printStackTrace();
    }

  }
}

最后来温习一下整个流程吧:

  1. 首先构建两个Wrapper,把servlet的签名与class信息set进去
  2. 然后创建上下文(Context),把上面创建的两个包装器加为子容器
  3. 随后构建一个mapper,设置好协议,再加入到容器中
  4. 往容器中添加监听器
  5. 给servlet加上映射路径
  6. 构建HttpConnector,并把容器添加进去
  7. 初始化连接器,启动连接器,启动容器
  8. 停止容器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值