一、Server的初始化
在Catalina.createStartDigester()方法中指定了由哪些实现类去实现对应的接口,那么这些组件是如何实现Lifeycle接口的?
1. 总览生命周期接口的实现方式
下图在上一篇图二的基础上补充了实现逻辑,见下图中的紫色部分(仅用于展示结构关系,未画所有Lifeycle相关组件):
(图一)
在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()是预留给子类实现的,由子类通过重写此方法来实现自己的个性逻辑。
为什么要这样设计呢?这就是模板方法模式。