二.观察者模式使用(Tomcat)
Tomcat生命周期管理
Tomcat的生命周期管理采用观察者模式。所涉及的类有:
- Lifecycle(event source):相当于抽象主题角色,所有的容器类与组件实现类都实现了这个接口。如StandardContext.
- LifecycleListener(event listener):相当于抽象观察者角色,具体的实现类有ContextConfig, HostConfig, EngineConfig类,它们在容器启动时与停止时触发。
- LifecycleEvent(event object):生命周期事件,对主题与发生的事件进行封装。
- LifecycleSupport:生命周期管理的实用类,提供对观察者的添加,删除及通知观察者的方法。
LifecycleException:生命周期异常类。
1.Lifecycle接口
Lifecycle相当于观察者模式中的抽象主题角色(Observable),它定义了添加、删除及通知管理者的方法。
还定义了与生命周期相关的6个事件。Start和stop方法是Lifecycle最重要的两个方法,分别代表启动与停止。所有四种容器的标准实现类(StandardEngine, StandardHost, StandardContext,StandardWrapper)和基本组件(Logger,Loader,Manager等)的实现类都实现了Lifecycle接口,这意义着它们都是具体的观察者,具有启动和停止方法。容器启动时,主要做三件事:调用组件的启动方法,启动组件;调用子容器的启动方法,启动子容器;通知容器的观察者,使其执行相应的启动动作。子容器启动也做这三件事,这样整个Tomcat便启动了。Tomcat的停止也类似。
package com.apache.catalina;
import org.apache.catalina.LifecycleException;
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 void removeLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
//主题的启动与停止方法
public void start()throws LifecycleException;
public void stop()throws LifecycleException;
}
2.实现LifecycleListener 通知接口(类似于调用Spring的onApplicationEvent方法)
LifecycleListener相当于观察者模式中的抽象观察者角色(Observer),可以看到它与Observer非常的类似,都只有一个更新自己的方法。不同的是,Observer 更新方法中,有两个参数:Observable与Object,而LifecycleListener中只有一个参数LifecycleEvent,这正是对前面两个参数的封装。
public interface LifecycleListener {
/**
* Acknowledge the occurrence of the specified event.
* @param event LifecycleEvent that has occurred
*/
public void lifecycleEvent(LifecycleEvent event);
}
3. 调用LifecycleSupport工具类的fireLifecycleEvent发布通知(类似于调用spring的publishEvent方法)
遍历所有的LifecycleListener调用其lifecycleEvent方法.
/**
* Notify all lifecycle event listeners that a particular event has
* occurred for this Container. The default implementation performs
* this notification synchronously using the calling thread.
*
* @param type Event type
* @param data Event data
*/
public void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
LifecycleListener interested[] = listeners;
for (int i = 0; i < interested.length; i++)
interested[i].lifecycleEvent(event);
}
真正调用的地方只有lifecyclebase,只要类只要继承该类即可发布通知.
/**
* Allow sub classes to fire {@link Lifecycle} events.
*
* @param type Event type
* @param data Data associated with event.
*/
protected void fireLifecycleEvent(String type, Object data) {
lifecycle.fireLifecycleEvent(type, data);
}
观察者模式贯穿整个tomcat的生命周期.
例:StandardServer的fireLifecycleEvent和setState都会触发通知
@Override
protected void startInternal() throws LifecycleException {
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);
globalNamingResources.start();
// Start our defined Services
synchronized (servicesLock) {
for (int i = 0; i < services.length; i++) {
services[i].start();
}
}
}