Tomcat中lifecycle在组件启动中的作用

通过lifecycle接口控制各个组件的生命周期。
那么它是怎么控制的呢?
看下lifecycle接口定义
lifecycle可以触发的事件如下final定义。

public interface 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";

    public void addLifecycleListener(LifecycleListener listener);
    public LifecycleListener[] findLifecycleListeners();
    public void removeLifecycleListener(LifecycleListenerlistener);
    public void start() throws LifecycleException;
    public void stop() throws LifecycleException;
}
复制代码

各个组件必须实现start()stop()方法供父组件调用,从而实现其启动和关闭。 组件注册监听器 监听该组件的事件的发生。
实际使用时simplecontext组件实现lifestyle接口。同时在simplecontext里定义一个变量持有LifecycleSupport实例。这样就可以用其方法了。 (为什么要实现(自己写实现方法,然后调用LifecycleSupport实例的方法,因为它持有LifecycleSupport对象.)

public class SimpleContext implements Context, Pipeline, Lifecycle {
  protected LifecycleSupport lifecycle = new LifecycleSupport(this);
//持有LifecycleSupport对象
复制代码

监听器处理逻辑 启动类增加一个监听器,调用LifecycleSupport方法加入监听器数组。 系统启动时发送事件,将事件传给各个监听器. 可以看出LifecycleSupport是整个过程的中心。看下LifecycleSupport类。 其构造方法持有一个lifecycle实例。

public final class LifecycleSupport {

    public LifecycleSupport(Lifecycle lifecycle) {
        super();
        this.lifecycle = lifecycle;
    }

    private Lifecycle lifecycle = null;

     *///存储了所有的监听器
    private LifecycleListener listeners[] = new LifecycleListener[0];

    public void addLifecycleListener(LifecycleListener listener) {
      synchronized (listeners) {
          LifecycleListener results[] = new LifecycleListener[listeners.length + 1];
          for (int i = 0; i < listeners.length; i++)
              results[i] = listeners[i];
          results[listeners.length] = listener;
          listeners = results;
      }
    }

    public LifecycleListener[] findLifecycleListeners() {

        return listeners;

    }

    public void  fireLifecycleEvent(String type, Object data) {

        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = null;
        synchronized (listeners) {
            interested = (LifecycleListener[]) listeners.clone();
        }
        //给所有的监听器  都发送这个事件
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);

    }

    public void removeLifecycleListener(LifecycleListener listener) {

        synchronized (listeners) {
            int n = -1;
            for (int i = 0; i < listeners.length; i++) {
                if (listeners[i] == listener) {
                    n = i;
                    break;
                }
            }
            if (n < 0)
                return;
            LifecycleListener results[] =
              new LifecycleListener[listeners.length - 1];
            int j = 0;
            for (int i = 0; i < listeners.length; i++) {
                if (i != n)
                    results[j++] = listeners[i];
            }
            listeners = results;
        }

    }


}
复制代码
public final class Bootstrap {
  public static void main(String[] args) {
    Connector connector = new HttpConnector();
    Wrapper wrapper1 = new SimpleWrapper();//实现了lifecycle接口
    wrapper1.setName("Primitive");
    wrapper1.setServletClass("PrimitiveServlet");
    Wrapper wrapper2 = new SimpleWrapper();//实现了lifecycle接口
    wrapper2.setName("Modern");
    wrapper2.setServletClass("ModernServlet");
  //SimpleContext实现Lifecycle接口,为什么要实现(自己写实现方法,然后调用LifecycleSupport实例的方法)
    Context context = new SimpleContext();//实现了lifecycle接口
    context.addChild(wrapper1);
    context.addChild(wrapper2);

    Mapper mapper = new SimpleContextMapper();
    mapper.setProtocol("http");
    LifecycleListener listener = new SimpleContextLifecycleListener();
    //调simpleContext的addLifecycleListener,内部调用LifecycleSupport的addLifecycleListener。
    ((Lifecycle) context).addLifecycleListener(listener);
    context.addMapper(mapper);
    Loader loader = new SimpleLoader();
    context.setLoader(loader);
    // context.addServletMapping(pattern, name);
    context.addServletMapping("/Primitive", "Primitive");
    context.addServletMapping("/Modern", "Modern");
    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();
    }
  }
}
复制代码

start()是如何启动上面实现了Lifecycle接口的组件呢?

首先先检查是否started了,若是,抛异常.
然后利用LifecycleSupport发送fireLifecycleEvent发送BEFORE_START_EVENT事件

 public void  fireLifecycleEvent(String type, Object data) {

        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = null;
        synchronized (listeners) {
            interested = (LifecycleListener[]) listeners.clone();
        }
        //给所有的监听器  都发送这个事件
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);

    }
复制代码

然后启动类加载器

 if ((loader != null) && (loader instanceof Lifecycle))
        ((Lifecycle)loader).start();  //由主容器控制下属组件的启动,启动类加载器
复制代码

因为实现Lifecycle的组件,必须重写start()方法。所以调用相应组件的start()启动组件。
然后遍历启动子容器,调用相应的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();//启动子容器wrapper
      }
复制代码

然后启动管道

      if (pipeline instanceof Lifecycle)
        ((Lifecycle) pipeline).start();//启动管道
复制代码

最后发送事件

  lifecycle.fireLifecycleEvent(START_EVENT, null);//发送事件
复制代码

至此,有启动类控制的整个流程启动了。(本文只是一个sample,但是思想是相同的)

public synchronized void start() throws LifecycleException {
    if (started)
      throw new LifecycleException("SimpleContext has already started");
    //利用lifecycle = new LifecycleSupport(this)发送事件,在发送方法内调用监听器的方法来处理
    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();//启动子容器wrapper
      }

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

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);//发送事件
  }
复制代码

转载于:https://juejin.im/post/5b1a0174f265da6e0f70b3f5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值