在了解初始化之前,先了解一下tomcat核心接口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 void init() throws LifecycleException;//初始化
public void start() throws LifecycleException;//启动
public void stop() throws LifecycleException;//停止
public void destroy() throws LifecycleException;//销毁
lifecycle的注释中也形象描绘了这些状态变化。
* start()
* -----------------------------
* | |
* | init() |
* NEW -»-- INITIALIZING |
* | | | | ------------------«-----------------------
* | | |auto | | |
* | | \|/ start() \|/ \|/ auto auto stop() |
* | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |
* | | | | |
* | |destroy()| | |
* | --»-----«-- ------------------------«-------------------------------- ^
* | | | |
* | | \|/ auto auto start() |
* | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
* | \|/ ^ | ^
* | | stop() | | |
* | | -------------------------- | |
* | | | | |
* | | | destroy() destroy() | |
* | | FAILED ----»------ DESTROYING ---«----------------- |
* | | ^ | |
* | | destroy() | |auto |
* | --------»----------------- \|/ |
* | DESTROYED |
* | |
* | stop() |
* ----»-----------------------------»------------------------------
抽象类LifecycleBase实现了Lifecycle相关方法,并预留了几个模板方法给子类实现。
protected void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(this, type, data);
for (LifecycleListener listener : lifecycleListeners) {
listener.lifecycleEvent(event);
/**
* org.apache.catalina.core.StandardEngine#startInternal()执行super的startInternal方法
* org.apache.catalina.util.LifecycleBase#setState(org.apache.catalina.LifecycleState)会触发监听器
* 当对象是StandardHost时 监听器是HostConfig
* 当对象是StandardContext时 监听器是ContextConfig
*/
}
}
//初始化
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
try {
//设置当前状态为INITIALIZING 表示正在初始化
setStateInternal(LifecycleState.INITIALIZING, null, false);
initInternal();//模板方法 子类实现
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
handleSubClassException(t, "lifecycleBase.initFail", toString());
}
}
public final synchronized void start() throws LifecycleException {
if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
LifecycleState.STARTED.equals(state)) {//状态判断
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
}
return;
}
if (state.equals(LifecycleState.NEW)) {
init();//初始化
} else if (state.equals(LifecycleState.FAILED)) {//启动失败 则stop
stop();
} else if (!state.equals(LifecycleState.INITIALIZED) &&
!state.equals(LifecycleState.STOPPED)) {
invalidTransition(Lifecycle.BEFORE_START_EVENT);
}
try {
setStateInternal(LifecycleState.STARTING_PREP, null, false);//设置启动状态为STARTING_PREP
startInternal();//模板方法
if (state.equals(LifecycleState.FAILED)) {
// This is a 'controlled' failure. The component put itself into the
// FAILED state so call stop() to complete the clean-up.
stop();
} else if (!state.equals(LifecycleState.STARTING)) {//需要子类将状态设置为STARTING
// Shouldn't be necessary but acts as a check that sub-classes are
// doing what they are supposed to.
invalidTransition(Lifecycle.AFTER_START_EVENT);
} else {//父类再将状态修改为STARTED
setStateInternal(LifecycleState.STARTED, null, false);
}
} catch (Throwable t) {
// This is an 'uncontrolled' failure so put the component into the
// FAILED state and throw an exception.
handleSubClassException(t, "lifecycleBase.startFail", toString());
}
}
初始化的方法大概流程图如下:
org.apache.catalina.core.StandardServer#initInternal
protected void initInternal() throws LifecycleException {
super.initInternal();//注册jmx
// Register global String cache
// Note although the cache is global, if there are multiple Servers
// present in the JVM (may happen when embedding) then the same cache
// will be registered under multiple names
//注册到JMX
onameStringCache = register(new StringCache(), "type=StringCache");
// Register the MBeanFactory
MBeanFactory factory = new MBeanFactory();
factory.setContainer(this);
onameMBeanFactory = register(factory, "type=MBeanFactory");
// Register the naming resources jndi相关
globalNamingResources.init();
// Populate the extension validator with JARs from common and shared
// class loaders
if (getCatalina() != null) {//不会为空
ClassLoader cl = getCatalina().getParentClassLoader();//COMMON类加载器 URLClassLoader
// Walk the class loader hierarchy. Stop at the system class loader. 停止在系统类加载器
// This will add the shared (if present) and common class loaders
while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
if (cl instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
if (url.getProtocol().equals("file")) {
try {
File f = new File (url.toURI());
if (f.isFile() &&
f.getName().endsWith(".jar")) {
ExtensionValidator.addSystemResource(f);
}
} catch (URISyntaxException | IOException e) {
// Ignore
}
}
}
}
cl = cl.getParent();
}
}
// Initialize our defined Services 初始化service组件
for (Service service : services) {
service.init();//初始化 StandardService
}
org.apache.catalina.core.StandardService#initInternal
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) {//digester设置的
try {
connector.init();
} catch (Exception e) {
String message = sm.getString(
"standardService.connector.initFailed", connector);
log.error(message, e);
if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
throw new LifecycleException(message);
}
}
}
}
}
org.apache.catalina.core.StandardEngine#initInternal
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.
getRealm();
super.initInternal();//创建一个起停服务的线程池
}
org.apache.catalina.core.ContainerBase#initInternal
protected void initInternal() throws LifecycleException {
BlockingQueue<Runnable> startStopQueue = new LinkedBlockingQueue<>();
startStopExecutor = new ThreadPoolExecutor(//起停线程
getStartStopThreadsInternal(),
getStartStopThreadsInternal(), 10, TimeUnit.SECONDS,
startStopQueue,
new StartStopThreadFactory(getName() + "-startStop-"));
startStopExecutor.allowCoreThreadTimeOut(true);
super.initInternal();
}
相对start方法 init方法还是比较简单。