看透SpringMVC源码分析
Lifecycle接口
Tomcat通过org.apache.catalina.Lifecycle
接口统一管理生命周期,所有有生命周期的组件都实现了Lifecycle接口。
Lifecycle一共做了四件事:
- 定义了13个String类型常量,用于LifecycleEvent事件的type属性中,作用是区分组件发出的LifecycleEvent事件时的状态(如初始化前,启动前,启动中等)。
- 定义了三个管理监听器的方法
addLifecycleListener,findLifecycleListeners,removeLifecycleListener
- 定义了四个生命周期方法
init,start,stop和destroy
- 定义了获取当前状态的两个方法
getState
和getStateName
//org.apache.catalina.Lifecycle
public interface Lifecycle {
public static final String BEFORE_INIT_EVENT = "before_init";
public static final String AFTER_INIT_EVENT = "after_init";
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 static final String AFTER_DESTROY_EVENT = "after_destroy";
public static final String BEFORE_DESTROY_EVENT = "before_destroy";
public static final String PERIODIC_EVENT = "periodic";
public static final String CONFIGURE_START_EVENT = "configure_start";
public static final String CONFIGURE_STOP_EVENT = "configure_stop";
public void addLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);
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();
}
LifecycleBase
Lifecycle的默认实现类是org.apache.catalina.util.LifecycleBase
,所有的生命周期组件都直接或者间接的集成了LifecycleBase
它为Lifecycle接口提供了默认的实现。
- 监听器管理是专门使用了一个
LifecycleSupport
来完成的,LifecycleSupport中定义了一个成员变量LifecycleListener数组
,用来保存所有的监听器,没然后定义了添加,查找,删除和执行监听器的方法。 - 生命周期方法中设置了相应的模板方法,init,start,stop和destroy分别调用了abstract模板方法
initInternal,startInternal,stopInternal,destroyInternal
- 组件当前的生命周期状态,则由一个volatile成员变量
LifecycleState
保持。
三个管理监听器方法和一个执行监听器方法
监听管理的的添加,查找,删除和执行监听器的方法都是使用了LifecycleSupport来管理的。
//org.apache.catalina.util.LifecycleBase
public abstract class LifecycleBase implements Lifecycle {
//让LifecycleSupport持有当前对象this
private LifecycleSupport lifecycle = new LifecycleSupport(this);
//addLifecycleListener方法交由LifecycleSupport处理。
@Override
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
//findLifecycleListeners方法交由LifecycleSupport处理。
@Override
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
//removeLifecycleListener方法交由LifecycleSupport处理。
@Override
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
//fireLifecycleEvent方法交由LifecycleSupport处理。
protected void fireLifecycleEvent(String type, Object data) {
lifecycle.fireLifecycleEvent(type, data);
}
}
LifecycleBase中的addLifecycleListener,findLifecycleListeners,removeLifecycleListener以及fireLifecycleEvent方法分别调用了LifecycleSupport
的同名方法,LifecycleSupport 通过一个数组属性listeners来保存
//org.apache.catalina.util.LifecycleSupport
public final class LifecycleSupport {
//持有lifecycle的对象
private Lifecycle lifecycle = null;
public LifecycleSupport(Lifecycle lifecycle) {
super();
this.lifecycle = lifecycle;
}
//定义一个成员变量listeners,记录所有的的事件监听
private LifecycleListener listeners[] = new LifecycleListener[0];
//当监听发生变化时进行同步的同步锁
private final Object listenersLock = new Object();
//将listener添加至listeners[]中
public void addLifecycleListener(LifecycleListener listener) {
synchronized (listenersLock) {
LifecycleListener results[] = new LifecycleListener[listeners.length + 1];
for (int i = 0; i < listeners.length; i++)
results[i] = listeners[i];
results[listeners.length] = listener;
listeners = results;
}
}
//findLifecycleListeners,removeLifecycleListener略....
//通知所有listeners,触发type类型的事件
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);
}
}
四个生命周期方法
只拿init方法作为示例。
//org.apache.catalina.util.LifecycleBase
public abstract class LifecycleBase implements Lifecycle {
private volatile LifecycleState state = LifecycleState.NEW;
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
//init方法调用时,当前状态不是NEW抛出异常
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
/*
* enum LifecycleState {
* INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT);
* }
* 设置当前状态INITIALIZING,后续触发BEFORE_INIT_EVENT事件
*/
setStateInternal(LifecycleState.INITIALIZING, null, false);
//调用模板方法initInternal(),由子类实现
initInternal();
/*
* enum LifecycleState {
* INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT);
* }
* 设置当前状态INITIALIZED,后续触发AFTER_INIT_EVENT事件
*/
setStateInternal(LifecycleState.INITIALIZED, null, false);
}
protected abstract void initInternal() throws LifecycleException;
//省略start,stop,destroy 以及startInternal,stopInternal,destroyInternal
//设置当前状态,并触发该状态对应的事件
private synchronized void setStateInternal(LifecycleState state,
Object data, boolean check) throws LifecycleException {
//省略日志,check state部分代码....
this.state = state;
//触发state对应的事件
String lifecycleEvent = state.getLifecycleEvent();
if (lifecycleEvent != null) {
fireLifecycleEvent(lifecycleEvent, data);
}
}
}
获取当前状态
//org.apache.catalina.util.LifecycleBase
public abstract class LifecycleBase implements Lifecycle {
@Override
public LifecycleState getState() {
return state;
}
@Override
public String getStateName() {
return getState().toString();
}
}
典型的生命周期组件
在TOMCAT启动-源码跟踪中,Bootstrap.load() 的执行过程细节是:Bootstrap.load() --> Catalina.load() --> getServer().init() --> LifecycleBase.init() --> StandardServer.initInternal()
.start也是类似。
StandardServer
- Catalina在调用init(),start(),stop()
方法时,最终都调用的是LifecycleBase的同名方法,而在LifecycleBase内部又是调用的StandardServer的xxxInternal()
方法。
- Catalina在调用await()
方法时,则调用的是,StandardServer的同名方法
//org.apache.catalina.core.StandardServer
protected void initInternal() throws LifecycleException {
//JMX 省略....
//省略其他部分.....
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}
protected void startInternal() throws LifecycleException {
//省略其他部分.....
// Start our defined Services
synchronized (services) {
for (int i = 0; i < services.length; i++) {
services[i].start();
}
}
}
public void await() {
//server.xml中<Server port="8005" shutdown="SHUTDOWN">
//port默认8005,shutdown默认值为SHUTDOWN
//如果端口是-2,则不进入方法,直接返回。
if( port == -2 ) {
return;
}
//如果端口是-1则进入循环,但是无法通过网络命令退出
if( port==-1 ) {
try {
awaitThread = Thread.currentThread();
while(!stopAwait) {
Thread.sleep( 10000 );
}
} finally {
awaitThread = null;
}
return;
}
//如果不是-1,-2(应该是一个大于0的端口),则会新建一个监听关闭命令的serverSocket;
awaitSocket = new ServerSocket(port, 1,InetAddress.getByName(address));
awaitThread = Thread.currentThread();
while (!stopAwait) {
ServerSocket serverSocket = awaitSocket;
if (serverSocket == null) {
break;
}
//监听关闭连接
Socket socket = serverSocket.accept();
StringBuilder command = new StringBuilder();
InputStream stream =socket.getInputStream();
//匹配关闭命令是否等于"SHUTDOWN"
boolean match = command.toString().equals(shutdown);
if (match) {
break;
}
}
}
StandardService
StandardService的默认实现是org.apache.catalina.core.StandardService
,在StandardServerinit(),start()
方法,会循环调用Service的start(),init()
方法,
最终也会经过LifecycleBase最终调用StandardService的initInternal(),startInternal()
方法。
//org.apache.catalina.core.StandardService
protected void initInternal() throws LifecycleException {
super.initInternal();
//初始化container
if (container != null) {
container.init();
}
//Executors:Connectors线程池
for (Executor executor : findExecutors()) {
if (executor instanceof LifecycleMBeanBase) {
((LifecycleMBeanBase) executor).setDomain(getDomain());
}
executor.init();
}
//初始化Connectors
synchronized (connectors) {
for (Connector connector : connectors) {
connector.init();
}
}
}
protected void startInternal() throws LifecycleException {
setState(LifecycleState.STARTING);
//首先启动Container
if (container != null) {
synchronized (container) {
container.start();
}
}
synchronized (executors) {
for (Executor executor: executors) {
executor.start();
}
}
//其次启动Connectors
synchronized (connectors) {
for (Connector connector: connectors) {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();
}
}
}
}
其中executor
配置在Server.xml中,默认是备注释掉,未开启。
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
</Service>
</Server>
上述配置表示Connector配置一个叫做tomcatThreadPool
的线程池,最多可同时启用150个线程,至少要有4个可用线程。