引言

本篇文章从一段代码开始,Catalina类中的laod()方法中:

1
2
3
4
5
6
7
8
9
10
11
12
13
//略......
// Start the new server
try {
//生命周期init方法
getServer().init();
} catch (LifecycleException e) {
if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
throw new java.lang.Error(e);
} else {
log.error("Catalina.start", e);
}
}
//略......

getServer获取的是当前持有的StandardServer,当然调用的init方法也是它的。
具体入口在StandardServer父类LifecycleBase中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public final synchronized void init() throws LifecycleException {
//如果state不是LifecycleState.NEW,执行下面的逻辑
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());
}
}

观察者模式的体现

setStateInternal方法

1
2
3
4
5
6
7
8
9
10
private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)
throws LifecycleException {
//略......

this.state = state;
String lifecycleEvent = state.getLifecycleEvent();
if (lifecycleEvent != null) {
fireLifecycleEvent(lifecycleEvent, data);
}
}

观察者模式的核心,触发生命周期事件:BEFORE_INIT_EVENT、AFTER_INIT_EVENT、START_EVENT、
BEFORE_START_EVENT、AFTER_START_EVENT、STOP_EVENT、BEFORE_STOP_EVENT、AFTER_STOP_EVENT、AFTER_DESTROY_EVENT、
BEFORE_DESTROY_EVENT、PERIODIC_EVENT、CONFIGURE_START_EVENT、CONFIGURE_STOP_EVENT;

fireLifecycleEvent

1
2
3
4
5
6
protected void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(this, type, data);
for (LifecycleListener listener : lifecycleListeners) {
listener.lifecycleEvent(event);
}
}

最后会依次调用组件的监听者,找个简单的例子VersionLoggerListener:

VersionLoggerListener

1
2
3
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Server>

这个类实现了LifecycleListener接口,也就是会重写lifecycleEvent方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 public void lifecycleEvent(LifecycleEvent event) {
if (Lifecycle.BEFORE_INIT_EVENT.equals(event.getType())) {
log();
}
}
private void log() {
log.info(sm.getString("versionLoggerListener.serverInfo.server.version",
ServerInfo.getServerInfo()));
log.info(sm.getString("versionLoggerListener.serverInfo.server.built",
ServerInfo.getServerBuilt()));
log.info(sm.getString("versionLoggerListener.serverInfo.server.number",
ServerInfo.getServerNumber()));
log.info(sm.getString("versionLoggerListener.os.name",
System.getProperty("os.name")));
log.info(sm.getString("versionLoggerListener.os.version",
System.getProperty("os.version")));
log.info(sm.getString("versionLoggerListener.os.arch",
System.getProperty("os.arch")));
log.info(sm.getString("versionLoggerListener.java.home",
System.getProperty("java.home")));
log.info(sm.getString("versionLoggerListener.vm.version",
System.getProperty("java.runtime.version")));
log.info(sm.getString("versionLoggerListener.vm.vendor",
System.getProperty("java.vm.vendor")));
log.info(sm.getString("versionLoggerListener.catalina.base",
System.getProperty("catalina.base")));
log.info(sm.getString("versionLoggerListener.catalina.home",
System.getProperty("catalina.home")));

if (logArgs) {
List<String> args = ManagementFactory.getRuntimeMXBean().getInputArguments();
for (String arg : args) {
log.info(sm.getString("versionLoggerListener.arg", arg));
}
}

if (logEnv) {
SortedMap<String, String> sortedMap = new TreeMap<>(System.getenv());
for (Map.Entry<String, String> e : sortedMap.entrySet()) {
log.info(sm.getString("versionLoggerListener.env", e.getKey(), e.getValue()));
}
}

if (logProps) {
SortedMap<String, String> sortedMap = new TreeMap<>();
for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) {
sortedMap.put(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
}
for (Map.Entry<String, String> e : sortedMap.entrySet()) {
log.info(sm.getString("versionLoggerListener.prop", e.getKey(), e.getValue()));
}
}
}

各种的日志打印。也就是说我们也可以自己实现监听器,只有实现LifecycleListener接口,重写lifecycleEvent方法,再配置到Server.xml中即可。

各种initInternal

StandardServer的initInternal方法

这个方法是模板模式体现,具体由实现者提供:

1
2
3
4
5
6
7
8
9
protected void initInternal() throws LifecycleException {

super.initInternal();
//略了
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}

最后会调用services的各个init方法,当然套路是一样的,这里的service是StandardService实例。

StandardService的initInternal方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
protected void initInternal() throws LifecycleException {

super.initInternal();

if (engine != null) {
engine.init();
}

// Initialize any Executors
for (Executor executor : findExecutors()) {
if (executor instanceof JmxEnabled) {
((JmxEnabled) executor).setDomain(getDomain());
}
executor.init();
}

// Initialize mapper listener
mapperListener.init();

// Initialize our defined Connectors
synchronized (connectorsLock) {
for (Connector connector : connectors) {
connector.init();
}
}
}

代码不用注释也能看懂,这里再看engine.init与connector.init()

StandardEngine的initInternal方法

1
2
3
4
5
6
7
protected void initInternal() throws LifecycleException {
// Ensure that a Realm is present before any attempt is made to start
// one. This will create the default NullRealm if necessary.
//Realm域提供了一种用户密码与web应用的映射关系。
getRealm();
super.initInternal();
}

Connector的initInternal方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
protected void initInternal() throws LifecycleException {
super.initInternal();
if (protocolHandler == null) {
throw new LifecycleException(
sm.getString("coyoteConnector.protocolHandlerInstantiationFailed"));
}
// Initialize adapter
adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);
// Make sure parseBodyMethodsSet has a default
if (null == parseBodyMethodsSet) {
setParseBodyMethods(getParseBodyMethods());
}
if (protocolHandler.isAprRequired() && !AprLifecycleListener.isAprAvailable()) {
throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoApr",
getProtocolHandlerClassName()));
}
if (AprLifecycleListener.isAprAvailable() && AprLifecycleListener.getUseOpenSSL() &&
protocolHandler instanceof AbstractHttp11JsseProtocol) {
AbstractHttp11JsseProtocol<?> jsseProtocolHandler =
(AbstractHttp11JsseProtocol<?>) protocolHandler;
if (jsseProtocolHandler.isSSLEnabled() &&
jsseProtocolHandler.getSslImplementationName() == null) {
// OpenSSL is compatible with the JSSE configuration, so use it if APR is available
jsseProtocolHandler.setSslImplementationName(OpenSSLImplementation.class.getName());
}
}
try {
protocolHandler.init();
} catch (Exception e) {
throw new LifecycleException(
sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e);
}
}

协议的初始化操作。

这篇文章就简单分析了一下Tomcat生命周期的一些套路,还有涉及到的两个设计模式:模板模式与观察者模式。