拆解Tomcat10: (五) 核心组件的协调控制与设计模式解析(一)

一、Server的初始化

在Catalina.createStartDigester()方法中指定了由哪些实现类去实现对应的接口,那么这些组件是如何实现Lifeycle接口的?


1. 总览生命周期接口的实现方式

下图在上一篇图二的基础上补充了实现逻辑,见下图中的紫色部分(仅用于展示结构关系,未画所有Lifeycle相关组件):


拆解Tomcat10: (五) 核心组件的协调控制与设计模式解析(一)(图一)

在Lifeycle接口中,定义了初始化(init)、启动(start)、停止(stop)、销毁(destory)、获取当前状态(getState)等方法,从Lifeycle的名字也可以知道,这个接口用于定义对象的生命周期,即生老病死的过程。

public interface Lifecycle {
    public void init() throws LifecycleException;
    public void start() throws LifecycleException;
    public void stop() throws LifecycleException;
    public void destroy() throws LifecycleException;
    public LifecycleState getState();
    public String getStateName();
}

2. 通用抽象类

直接实现Lifeycle接口的是LifecycleBase类,这是一个抽象类。以其实现init()方法为例:

    @Override
    public final synchronized void init() throws LifecycleException {
        if (!state.equals(LifecycleState.NEW)) {
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }

        try {
            // 触发相应状态的事件
            setStateInternal(LifecycleState.INITIALIZING, null, false);
            initInternal();
            setStateInternal(LifecycleState.INITIALIZED, null, false);
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.initFail", toString());
        }
    }


    /**
     * 子类实现此方法以执行所需的任何实例初始化。
     *
     * @throws LifecycleException If the initialisation fails
     */
    protected abstract void initInternal() throws LifecycleException;

在LifecycleBase类中有两个对应的init相关方法,首先init()方法Override父类的方法,通过setStateInternal方法触发相应状态的事件(具体后文描述,不是此处重点),然后调用另一个抽象方法initInternal()。


3. 子类的实现逻辑

这里预留的initInternal()方法是做什么用的呢,看一下StandardServer类中对此方法的具体实现:

    @Override
    protected void initInternal() throws LifecycleException {
        // 执行父级的逻辑
        super.initInternal();

        // 初始化 utility executor
        reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
        register(utilityExecutor, "type=UtilityExecutor");

        // 注册全局字符串缓存注意虽然缓存是全局的,但如果JVM中存在多个服务器(嵌入时可能会发生),那么相同的缓存将以多个名称注册
        onameStringCache = register(new StringCache(), "type=StringCache");

        // 注册 MBeanFactory
        MBeanFactory factory = new MBeanFactory();
        factory.setContainer(this);
        onameMBeanFactory = register(factory, "type=MBeanFactory");

        // 注册并初始化 naming resources
        globalNamingResources.init();

        //此处省略了加载器相关的代码
        
        
        // 初始化定义的 Services
        for (Service service : services) {
            service.init();
        }
    }

可以看到这里是具体Server相关的代码,也就是说,initInternal()是预留给子类实现的,由子类通过重写此方法来实现自己的个性逻辑。

为什么要这样设计呢?这就是模板方法模式。

上一篇:AJAX 学习


下一篇:HTTP和HTTPS区别如下