Tomcat源码分析-LifecycleMBeanBase

类概况

关注这个类是因为上一回跟踪了AccessLogValve类,它是LifecycleMBeanBase的一个子类,搞清楚这个类的各个子类结构,也就理顺了Tomcat容器中各个组件的协助流程了。管中窥豹,还是先从这个顶层抽象类开始吧。
这个类的结构很简单,类图绘制如下:

这里写图片描述

父类LifecycleBase

Base implementation of the Lifecycle interface that implements the
state transition rules for start() and stop()

这是源码的注释,说明了这个类是Lifecycle接口的基本实现类,Tomcat中的组件都需要实现Lifecycle接口,以提供一种标准的流程来启动和关闭组件。从类图来看,它主要提供了跟组件生命周期有关的方法,如启动、停止、销毁。
值得关注的是,它是一个抽象类,而且除了跟LifecycleListener有关的方法外,其他方法都是成对出现:例如start(),startInternal()。这是典型的模版方法设计模式的运用,start()方法是公共final的模版方法,定义了启动流程,而流程中的各个操作都是protected abstract方法,由子类提供且只能由子类调用。源码如下:

 public final synchronized void start() throws LifecycleException {

        if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                LifecycleState.STARTED.equals(state)) {

            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
            }

            return;
        }

        if (state.equals(LifecycleState.NEW)) {
            init();
        } else if (state.equals(LifecycleState.FAILED)) {
            stop();
        } else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }

        try {
            setStateInternal(LifecycleState.STARTING_PREP, null, false);
            startInternal();
            if (state.equals(LifecycleState.FAILED)) {
                // This is a 'controlled' failure. The component put itself into the
                // FAILED state so call stop() to complete the clean-up.
                stop();
            } else if (!state.equals(LifecycleState.STARTING)) {
                // Shouldn't be necessary but acts as a check that sub-classes are
                // doing what they are supposed to.
                invalidTransition(Lifecycle.AFTER_START_EVENT);
            } else {
                setStateInternal(LifecycleState.STARTED, null, false);
            }
        } catch (Throwable t) {
        }
    }

其他几个方法基本类似。
此外,这是一个简单的观察者模式的应用,LifecycleBase和LifecycleSupport是观察者模式实现的两个类。触发LifecycleEvent事件时根据当前lifecycle对象创建事件,然后以此通知列表中的监听者。

LifecycleMBeanBase

JmxEnable是Java Managed Bean相关的功能,这个还有待继续研究。它也是个抽象类,实现了父类的initInternal()和destroyInternal(),这两个方法也很简单,就是对ManabedBean的注册和注销。源码如下:

protected void initInternal() throws LifecycleException {

        // If oname is not null then registration has already happened via
        // preRegister().
        if (oname == null) {
            mserver = Registry.getRegistry(null, null).getMBeanServer();

            oname = register(this, getObjectNameKeyProperties());
        }
    }
  @Override
  protected void destroyInternal() throws LifecycleException {
        unregister(oname);
    }

注意类图中,LifecycleMBeanBase类的getDomain方法定义的是final类型,它调用了getInternalDomain()这个protected abstract方法,这也是典型的模版方法模式的应用。

启示录

首先,就是模版方法的运用,值得学习。
其次,这个类图中有两个接口,可以发现Tomcat源码中接口方法中通常会定义一对getXX,setXX这样的方法,那么它的实现类必定会有一个这样类型的成员变量。

此外,还可以通过委派其他类来实现接口中的方法。例如LifecycleBase方法中对LifecycleEventListener的支持就是通过成员变量lifecycle:LifecycleSupport实现的。这种类的设计思路,总结一下还是很受启发的。

最后,就是protected权限的巧妙运用,LifecycleBase中以Internal为后缀的那些方法,可以理解为是内部方法,只有自己和子类才能调用。这也解答了我的疑虑:之前我在想如果调用者直接调用startInternal方法而不调start怎么办呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值