tomcat中有很多组件,要对这些组件进行生命周期的管理非常困难,tomcat中采用的是抽象出一个生命周期管理接口,然后所有的组件都实现该接口,当父组件启动时,同事负责将子组件启动起来,从而完成整tomcat的初始、启动、结束等动作。
来看下tomcat启动的过程,首先构造Bootstrap类,调用其中的init方法,完成类加载器的初始化,方便后面加载类使用,然后调用其中的load方法,实际上tomcat真正的启动动作是由Catalina类完成的。而这其中在BootStrap中调用Catalina的load方法是通过反射完成的,按照how tomcat works的说法,这是为了解耦,可以方便的改变启动的方式。Catalina类继承了Embedded类,而Embedded又继承了StandardService类。而像StandardService或者ContainerBase(Container组件的基础父类)都实现了Lifecycle接口。从而可以方便的进行统一的处理。
StandardService中持有一个Server的引用,表示该Server下有一个Service服务,标准的Server实现是StandardServer:
// Start the new server
//获取Server这里是一个标准的实现StandardService
if (getServer() instanceof Lifecycle) {
try {
//返回StandardServer并调用初始化方法
getServer().initialize();
} 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);
}
}public void initialize()
throws LifecycleException
{
if (initialized) {
log.info(sm.getString("standardServer.initialize.initialized"));
return;
}
//调用lifecycle的fireLifecycleEvent方法
lifecycle.fireLifecycleEvent(INIT_EVENT, null);
initialized = true;
...........
一个Server可以有多个Service,分别进行初始化
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].initialize();
}
}public void fireLifecycleEvent(String type, Object data) {
//初始化话状态
if (Lifecycle.INIT_EVENT.equals(type)) {
state = "INITIALIZED";
} else if (Lifecycle.BEFORE_START_EVENT.equals(type)) {
state = "STARTING_PREP";
} else if (Lifecycle.START_EVENT.equals(type)) {
state = "STARTING";
} else if (Lifecycle.AFTER_START_EVENT.equals(type)) {
state = "STARTED";
} else if (Lifecycle.BEFORE_STOP_EVENT.equals(type)) {
state = "STOPPING_PREP";
} else if (Lifecycle.STOP_EVENT.equals(type)) {
state = "STOPPING";
} else if (Lifecycle.AFTER_STOP_EVENT.equals(type)) {
state = "STOPPED";
} else if (Lifecycle.DESTROY_EVENT.equals(type)) {
state = "DESTROYED";
}
//完成生命周期事件的生成
LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
获取该组件对应的生命周期监听器
LifecycleListener interested[] = listeners;
for (int i = 0; i < interested.length; i++)
//传递该事件,通过监听器完成组件的初始化动作
interested[i].lifecycleEvent(event);
}public StandardServer() {
super();
ServerFactory.setServer(this);
globalNamingResources = new NamingResources();
globalNamingResources.setContainer(this);
if (isUseNaming()) {
if (namingContextListener == null) {
namingContextListener = new NamingContextListener();
addLifecycleListener(namingContextListener);
}
}
}<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
具体这些监听器都做了哪些初始化动作,就不看了,太多了。当完成自己的初始化动作后,调用子组件这里是service的初始化方法,我们知道一个service由一个container和多个connector组成,看了StandardService源码确实是这样的,来看下service的初始化动作:
public void initialize()
throws LifecycleException
{
// Service shouldn't be used with embeded, so it doesn't matter
if (initialized) {
if(log.isInfoEnabled())
log.info(sm.getString("standardService.initialize.initialized"));
return;
}
initialized = true;
if( oname==null ) {
try {
// Hack - Server should be deprecated...
//获取service中的Container这里是engine(StandardEngine)
Container engine=this.getContainer();
domain=engine.getName();
oname=new ObjectName(domain + ":type=Service,serviceName="+name);
this.controller=oname;
Registry.getRegistry(null, null)
.registerComponent(this, oname, null);
Executor[] executors = findExecutors();
for (int i = 0; i < executors.length; i++) {
ObjectName executorObjectName =
new ObjectName(domain + ":type=Executor,name=" + executors[i].getName());
Registry.getRegistry(null, null)
.registerComponent(executors[i], executorObjectName, null);
}
} catch (Exception e) {
log.error(sm.getString("standardService.register.failed",domain),e);
}
}
if( server==null ) {
// Register with the server
// HACK: ServerFactory should be removed...
ServerFactory.getServer().addService(this);
}
// Initialize our defined Connectors
//默认的connector是Connector[HTTP/1.1-8080], Connector[AJP/1.3-8009]这两种
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++) {
try {
//调用子组件的初始化动作
connectors[i].initialize();
} catch (Exception e) {
String message = sm.getString(
"standardService.connector.initFailed",
connectors[i]);
log.error(message, e);
if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))
throw new LifecycleException(message);
}
}
}
}public void initialize()
throws LifecycleException
{
this.initialized = true;
......
// Initializa adapter
//初始化connector的成员变量adapter和protocolHandler,这两个类后面会讲到
adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);
// Make sure parseBodyMethodsSet has a default
if( null == parseBodyMethodsSet )
setParseBodyMethods(getParseBodyMethods());
//反射调用,这个反射工具值得好好学习一下
IntrospectionUtils.setProperty(protocolHandler, "jkHome",
System.getProperty("catalina.base"));
try {
//子组件的初始化,Http11Protocol和JkCoyoteHandler
protocolHandler.init();
} catch (Exception e) {
throw new LifecycleException
(sm.getString
("coyoteConnector.protocolHandlerInitializationFailed", e));
}
}public void init() throws Exception {
//endpoint类,该类为JIoEndpoin,是一个非常重要的类,有BIO和NIO的实现,后面会讲到
endpoint.setName(getName());
//cHandle同样是另外一个很重要的类Http11ConnectionHandler,该类为Http11Protocol的内部类
endpoint.setHandler(cHandler);
// Verify the validity of the configured socket factory
try {
if (isSSLEnabled()) {
sslImplementation =
SSLImplementation.getInstance(sslImplementationName);
//这里终于看到很熟悉的概念了,socket!不过是一个ServerSocket的工厂,很明显要去生产serverSocket
socketFactory = sslImplementation.getServerSocketFactory();
//咦?这里将这个工厂地址告诉了endpoint,可以大胆猜测下,ServerSocket的创建可能在endPoint中完成。
endpoint.setServerSocketFactory(socketFactory);
} else if (socketFactoryName != null) {
socketFactory = (ServerSocketFactory) Class.forName(socketFactoryName).newInstance();
endpoint.setServerSocketFactory(socketFactory);
}
} catch (Exception ex) {
log.error(sm.getString("http11protocol.socketfactory.initerror"),
ex);
throw ex;
}
//不过debug的时候,上面的socketFactory始终是null,不知道socketFactoryName是从哪里获取。
if (socketFactory!=null) {
Iterator<String> attE = attributes.keySet().iterator();
while( attE.hasNext() ) {
String key = attE.next();
Object v=attributes.get(key);
socketFactory.setAttribute(key, v);
}
}
//endpoint的初始化动作
try {
endpoint.init();
} catch (Exception ex) {
log.error(sm.getString("http11protocol.endpoint.initerror"), ex);
throw ex;
}
if (log.isInfoEnabled())
log.info(sm.getString("http11protocol.init", getName()));
}public void init()
throws Exception {
//这里的初始化动作,终于不那么晦涩了,很多熟悉的概念
if (initialized)
return;
// Initialize thread count defaults for acceptor
//初始化acceptor的个数,默认为1,acceptor负责接收客户端的连接。
if (acceptorThreadCount == 0) {
acceptorThreadCount = 1;
}
//这里我们并没有提供ServerSocketFactory,因此使用默认的工厂
if (serverSocketFactory == null) {
serverSocketFactory = ServerSocketFactory.getDefault();
}
if (serverSocket == null) {
try {
//终于要初始化serverSocket了,port经典的8080,backlog是连接队列的最大等待个数服务端
//某一时刻肯定只能处理一个客户端的连接,同一时刻其余连接全部放入等待队列中,如果满了,则拒绝连接
if (address == null) {
serverSocket = serverSocketFactory.createSocket(port, backlog);
} else {
serverSocket = serverSocketFactory.createSocket(port, backlog, address);
}
} catch (BindException orig) {
String msg;
if (address == null)
msg = orig.getMessage() + " <null>:" + port;
else
msg = orig.getMessage() + " " +
address.toString() + ":" + port;
BindException be = new BindException(msg);
be.initCause(orig);
throw be;
}
}
//if( serverTimeout >= 0 )
// serverSocket.setSoTimeout( serverTimeout );
initialized = true;
}
这里并没有涉及到service中的container初始化的动作,没错container并没有进行相应的初始化,但是很令人讨厌的一点是在engine或者context中确实有init方法,而这些方法是在start的时候调用的。start的过程下一节再去分析。
原文地址:http://blog.csdn.net/tangyongzhe/article/details/42321925