tomcat生命周期管理

Lifecycle接口


       tomcat通过org.apache.catalina.Lifecycle统一管理生命周期,所有有生命周期的组件都要实现Lifecycle接口。Lifecyle主要做了四件事:
- 定义了13个String常量,用于LifecycleEvent事件的type属性,用于区分组件发出的LifecycleEvent事件的状态。这种方法可以让多种状态都发送同一类型的事件,然后用一个属性来区分事件而不用定义多种事件。
- 定义了3个管理监听器的方法:addLifecycleListener、findLifecycleListener以及removeLifecycleListener,分别用来添加、查找和删除LifecycleListener类型的监听器。
- 定义了4个周期的方法:init、start、stop和destory,用于执行生命周期的各阶段操作。
- 定义了获取当前状态的两个方法getState和getStateName,用来获取当前的状态,getState的返回值Lifecycle是枚举类型,里面列举了生命周期的各个节点,getStateName返回String类型的状态名字。


public abstract interface Lifecycle
{
  public static final String BEFORE_INIT_EVENT = "before_init";
  public static final String AFTER_INIT_EVENT = "after_init";
  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 static final String AFTER_DESTROY_EVENT = "after_destroy";
  public static final String BEFORE_DESTROY_EVENT = "before_destroy";
  public static final String PERIODIC_EVENT = "periodic";
  public static final String CONFIGURE_START_EVENT = "configure_start";
  public static final String CONFIGURE_STOP_EVENT = "configure_stop";

  public abstract void addLifecycleListener(LifecycleListener paramLifecycleListener);

  public abstract LifecycleListener[] findLifecycleListeners();

  public abstract void removeLifecycleListener(LifecycleListener paramLifecycleListener);

  public abstract void init()
    throws LifecycleException;

  public abstract void start()
    throws LifecycleException;

  public abstract void stop()
    throws LifecycleException;

  public abstract void destroy()
    throws LifecycleException;

  public abstract LifecycleState getState();

  public abstract String getStateName();

  public static abstract interface SingleUse {}
}

LifecycleBase


       Lifecycle的默认实现是org.apache.catalina.until.LifecycleBase,所有实现了生命周期的组件都直接或者间接的继承了LifecycleBase,LifecycleBase为Lifecycle接口的方法提供了默认实现:监听管理器是专门使用LifecycleSupport类完成的,LifecycleSupport中定义了一个LifecycleListener类型的CopyOnWriteArrayList集合保存所有的监听器,并且定义了添加、查找、删除和执行的方法;生命周期方法中设置了相应的状态并且调用了相应的模板方法,init、start、stop和destory所对应的方法分别是initInternal、startInternal、stopInternal和destoryInternal,这四个方法由具体子类实现,对于子类来说,执行生命周期处理就是这四个方法;组件当前的状态在声明周期的四个方法已经设置好了。

三个管理监听器的方法


       管理监听器的添加、查找和删除的方法是使用LifecycleSupport来管理的:

 private final LifecycleSupport lifecycle = new LifecycleSupport(this);

public void addLifecycleListener(LifecycleListener listener)
  {
    this.lifecycle.addLifecycleListener(listener);
  }

  public LifecycleListener[] findLifecycleListeners()
  {
    return this.lifecycle.findLifecycleListeners();
  }

  public void removeLifecycleListener(LifecycleListener listener)
  {
    this.lifecycle.removeLifecycleListener(listener);
  }

Lifecycle中的addLifecycleListener、findLifecycleListener和removeLifecycleListener分别调用了LifecycleSupport中的同名方法,LifecycleSupport监听器是通过一个CopyOnWriteArrayList集合listeners来保存的,代码如下:

private final List<LifecycleListener> listeners = new CopyOnWriteArrayList();


  public void addLifecycleListener(LifecycleListener listener)
  {
    this.listeners.add(listener);
  }

  public LifecycleListener[] findLifecycleListeners()
  {
    return (LifecycleListener[])this.listeners.toArray(new LifecycleListener[0]);
  }

   public void removeLifecycleListener(LifecycleListener listener)
  {
    this.listeners.remove(listener);
  }
四个生命周期方法


       四个生命周期方法实现中首先判断当前状态是否匹配,如果不匹配执行相应方法使其匹配(如init之前调了start会先执行init),或者不处理甚至抛出异常,如果匹配或者处理后匹配了,则调用相应的模板方法并设置相应的状态。LifecycleBase中的状态是通过LifecycleState类型的state属性保存的,最开始初始值为LifecycleState.new。

public final synchronized void init() throws LifecycleException {
    //初始状态必须为new,不然抛出异常
    if (!this.state.equals(LifecycleState.NEW)) {
      invalidTransition("before_init");
    }
    try
    {
    //初始化之前设置状态为initing
      setStateInternal(LifecycleState.INITIALIZING, null, false);
      //通过模板方法执行初始化
      initInternal();
      //完成init后将状态设置为inited
      setStateInternal(LifecycleState.INITIALIZED, null, false);
    }
    catch (Throwable t)
    {
      ExceptionUtils.handleThrowable(t);
      setStateInternal(LifecycleState.FAILED, null, false);
      throw new LifecycleException(sm.getString("lifecycleBase.initFail", new Object[] { toString() }), t);
    }
  }


       因为init方法最先执行,所以状态必须为new,否则抛出异常,初始化之前把状态设置为initing,通过模板方法执行初始化后状态改为inited。invalidTransition(“before_init”)方法主要用来处理不合法的状态,内部抛出LifecycleException异常。

public final synchronized void start()
    throws LifecycleException
  {
    if ((LifecycleState.STARTING_PREP.equals(this.state)) || (LifecycleState.STARTING.equals(this.state)) || (LifecycleState.STARTED.equals(this.state)))
    {
      if (log.isDebugEnabled())
      {
        Exception e = new LifecycleException();
        log.debug(sm.getString("lifecycleBase.alreadyStarted", new Object[] { toString() }), e);
      }
      else if (log.isInfoEnabled())
      {
        log.info(sm.getString("lifecycleBase.alreadyStarted", new Object[] { toString() }));
      }
      return;
    }
    if (this.state.equals(LifecycleState.NEW)) {
      init();
    } else if (this.state.equals(LifecycleState.FAILED)) {
      stop();
    } else if ((!this.state.equals(LifecycleState.INITIALIZED)) && (!this.state.equals(LifecycleState.STOPPED))) {
      invalidTransition("before_start");
    }
    try
    {
      setStateInternal(LifecycleState.STARTING_PREP, null, false);
      startInternal();
      if (this.state.equals(LifecycleState.FAILED)) {
        stop();
      } else if (!this.state.equals(LifecycleState.STARTING)) {
        invalidTransition("after_start");
      } else {
        setStateInternal(LifecycleState.STARTED, null, false);
      }
    }
    catch (Throwable t)
    {
      ExceptionUtils.handleThrowable(t);
      setStateInternal(LifecycleState.FAILED, null, false);
      throw new LifecycleException(sm.getString("lifecycleBase.startFail", new Object[] { toString() }), t);
    }
  }


       start方法在启动前先判断是否启动了,如果启动了直接返回,如果没有初始化执行初始化操作,如果是失败状态就会调用stop关闭,其他状态则会抛出异常。如果状态是初始化刚完或者已经停止了,会将状态设置为STARTING_RESP,然后调用startInternal模板方法调用子类的具体启动逻辑进行启动,最后根据是否启动成功设置相应状态。stop和destory实现类似。

       设置状态的setInternal方法中除了设置状态还可以检查设置的状态是否符合逻辑,并在最后发布相应的事件:

private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)
    throws LifecycleException
  {
    if (log.isDebugEnabled()) {
      log.debug(sm.getString("lifecycleBase.setState", new Object[] { this, state }));
    }
    if (check)
    {
        //状态为空直接抛出异常,正常情况下不会为空
      if (state == null)
      {
        invalidTransition("null");

        return;
      }
      //状态不符合逻辑直接抛出异常 
      if ((state != LifecycleState.FAILED) && ((this.state != LifecycleState.STARTING_PREP) || (state != LifecycleState.STARTING)) && ((this.state != LifecycleState.STOPPING_PREP) || (state != LifecycleState.STOPPING)) && ((this.state != LifecycleState.FAILED) || (state != LifecycleState.STOPPING))) {
        invalidTransition(state.name());
      }
    }
    //设置为新状态
    this.state = state;
    //发布事件
    String lifecycleEvent = state.getLifecycleEvent();
    if (lifecycleEvent != null) {
      fireLifecycleEvent(lifecycleEvent, data);
    }
  }


       setStateInternal通过check参数判断是否需要检查传入参数的状态,如果需要检查则会检查传入的状态是否为空并检查是否符合逻辑,最后将传入的状态设置到state属性。并调用fireLifecycleEvent方法处理事件,firelifecycleEvent调用了LifecycleSupport的firecycleEvent方法来具体处理,代码如下:

  protected void fireLifecycleEvent(String type, Object data)
  {
    this.lifecycle.fireLifecycleEvent(type, data);
  }

LifecycleSupport的fireLifecycleEvent方法首先创建LifecycleEvent事件,然后遍历所有的监听器进行处理。

两个获取当前状态的方法


       在生命周期的相应方法中已经将状态设置到了state属性,所以获取状态的两个方法实现就非常简单了,直接将state返回就可以了:

public LifecycleState getState()
  {
    return this.state;
  }

  public String getStateName()
  {
    return getState().toString();
  }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值