2013-09-21
容器是tomcat的基础,tomcat通过容器来管理和维护tomcat组件,最外层的容器是Server,最内层的容器是Wrapper,容器提供了一些基础的功能,例如添加父容器,子容器,共享数据,数据隔离等。
Container
Container是tomcat中的容器接口,定义了容器所具有的方法和tomcat中容器的规范。容器接口提供了操作容器的方法,例如设置父容器和添加子容器,查找容器,添加监听容器事件的监听器,是invoke(Request, Response)处理HTTP协议请求的方法。
ContainerBase
ContainerBase是Container接口的基本实现,是个抽象类,在类中提供了Container大多数方法的实现,把一些容器公共实现抽象到ContainerBase实现。ContainerBase的功能是:实现了Container接口的大多数方法,把子类所需要实现的共同方法在基类中实现,避免在子类中重复编码,子类通过继承ContainerBase类来完成。
LifecycleSupport
ContainerBase抽象类中的属性,Lifecycle接口实现类,功能是负责管理注册在容器上面的LifecycleEvent监听类,监听容器的生命周期变更,集中管理监听器。
listeners
ContainerBase的属性,容器监听器数组,用户监听容器本身事件,监听的是ContainerEvent事件,与LifecycleEvent不同。
Loader
ContainerBase的属性,tomcat自己封装的类加载器,针对webapp安全的类加载,管理webapp的类加载,在java的类加载器体系中,不同类加载器加载的类实例是不能同时访问的。
Manager
ContainerBase的属性,Manager是用来管理在容器上面的Session池,负责Session的生命周期,从生成到销毁,Manager是一个管理Session池的一个方法集合接口。
cluster : Cluster
ContainerBase的属性,跟集群有关。
pipeline : Pipeline
ContainerBase的属性,很重要,是Valve链,功能是负责管理Valve,也是请求信息传递链,最终目的是ServletWrapper中。pipeline 决定Valve的顺序,控制请求信息,是容器间传递请求信息的桥梁。
support : PropertyChangeSupport
ContainerBase的属性,容器属性更新监听器集中管理,跟LifecycleSupport功能一样。
backgroundProcess()
Container接口方法,Container定义该方法的目的是启用一个后台进程来处理一些逻辑,比如重新加载配置,判断Session失效等。
ContainerBackgroundProcessor
ContainerBase基本容器的内部类,实现了Runnable接口,具体作用是作为一个后台程序定时触发backgroundProcess()后台处理方法。
/**
* Private thread class to invoke the backgroundProcess method of this
* container and its children after a fixed delay.
*/
protected class ContainerBackgroundProcessor implements Runnable {
public void run() {
while (!threadDone) {
try {
Thread.sleep(backgroundProcessorDelay * 1000L);//睡眠
} catch (InterruptedException e) {
;
}
if (!threadDone) {
//取类加载器,确保容器和子容器在同一个类加载器中
Container parent = (Container) getMappingObject();
ClassLoader cl = Thread.currentThread()
.getContextClassLoader();
if (parent.getLoader() != null) {
cl = parent.getLoader().getClassLoader();
}
processChildren(parent, cl);//调用容器的backgroundProcess()方法
}
}
}
/**
* 处理子容器
* @param container
* @param cl
*/
protected void processChildren(Container container, ClassLoader cl) {
try {
if (container.getLoader() != null) {
Thread.currentThread().setContextClassLoader(
container.getLoader().getClassLoader());
}
container.backgroundProcess();//调用后台处理方法
} catch (Throwable t) {
log.error("Exception invoking periodic operation: ", t);
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
Container[] children = container.findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i].getBackgroundProcessorDelay() <= 0) {
processChildren(children[i], cl);//处理子容器
}
}
}
}
init()
负责容器的初始化工作,主要有一下几步,
/**
* Init method, part of the MBean lifecycle. If the container was added via
* JMX, it'll register itself with the parent, using the ObjectName
* conventions to locate the parent.
*
* If the container was added directly and it doesn't have an ObjectName,
* it'll create a name and register itself with the JMX console. On
* destroy(), the object will unregister.
*
* @throws Exception
*/
public void init() throws Exception {
if (this.getParent() == null) {
// "Life" update
ObjectName parentName = getParentName();
// log.info("Register " + parentName );
if (parentName != null && mserver.isRegistered(parentName)) {
mserver.invoke(parentName, "addChild", new Object[] { this },
new String[] { "org.apache.catalina.Container" });
}
}
initialized = true;
}
start()
负责容器的启动工作,主要有以下几步,主要启动添加在容器上面的组件。
/**
* Prepare for active use of the public methods of this Component.
* 预启动的公有方法
* @exception LifecycleException
* if this component detects a fatal error that prevents it
* from being started
*/
public synchronized void start() throws LifecycleException {
// Validate and update our current component state
if (started) {
if (log.isInfoEnabled())
log.info(sm
.getString("containerBase.alreadyStarted", logName()));
return;
}
// Notify our interested LifecycleListeners
//开始启动事件监听
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
started = true;
// Start our subordinate components, if any
if ((loader != null) && (loader instanceof Lifecycle))
((Lifecycle) loader).start();//加载器启动
logger = null;
getLogger();
if ((logger != null) && (logger instanceof Lifecycle))
((Lifecycle) logger).start();
if ((manager != null) && (manager instanceof Lifecycle))
((Lifecycle) manager).start();//管理器启动
if ((cluster != null) && (cluster instanceof Lifecycle))
((Lifecycle) cluster).start();//集群从节点启动
if ((realm != null) && (realm instanceof Lifecycle))
((Lifecycle) realm).start();
if ((resources != null) && (resources instanceof Lifecycle))
((Lifecycle) resources).start();//资源启动
// Start our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).start();//启动子容器
}
// Start the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle)
((Lifecycle) pipeline).start();//监听pipe功能
// Notify our interested LifecycleListeners
//正在启动事件通知
lifecycle.fireLifecycleEvent(START_EVENT, null);
// Start our thread
threadStart();//启动线程
// Notify our interested LifecycleListeners
//完成启动事件通知
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
stop()
负责停止容器,所做的工作就是按照start()方法中组件启动的顺序逆序停止组件。
/**
* Gracefully shut down active use of the public methods of this Component.
* 优雅关闭容器的公有方法
* @exception LifecycleException
* if this component detects a fatal error that needs to be
* reported
*/
public synchronized void stop() throws LifecycleException {
// Validate and update our current component state
if (!started) {
if (log.isInfoEnabled())
log.info(sm.getString("containerBase.notStarted", logName()));
return;
}
// Notify our interested LifecycleListeners
//准备停止容器事件通知
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
// Stop our thread
threadStop();//停止线程
// Notify our interested LifecycleListeners
//停止容器事件通知
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
// Stop the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).stop();//pipe停止
}
// Stop our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).stop();//子容器停止
}
// Remove children - so next start can work
children = findChildren();
for (int i = 0; i < children.length; i++) {
removeChild(children[i]);//移除子容器
}
// Stop our subordinate components, if any
if ((resources != null) && (resources instanceof Lifecycle)) {
((Lifecycle) resources).stop();//资源停止
}
if ((realm != null) && (realm instanceof Lifecycle)) {
((Lifecycle) realm).stop();
}
if ((cluster != null) && (cluster instanceof Lifecycle)) {
((Lifecycle) cluster).stop();//集群子节点停止
}
if ((manager != null) && (manager instanceof Lifecycle)) {
((Lifecycle) manager).stop();//管理器停止
}
if ((logger != null) && (logger instanceof Lifecycle)) {
((Lifecycle) logger).stop();
}
if ((loader != null) && (loader instanceof Lifecycle)) {
((Lifecycle) loader).stop();
}
// Notify our interested LifecycleListeners
//完成停止容器事件通知
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
}
destroy()
负责销毁容器,主要工作是注销MBeanServer,移除父容器引用,移除容器
/**
* 停止容器
* @throws Exception
*/
public void destroy() throws Exception {
if (started) {
stop();
}
initialized = false;
// unregister this component
if (oname != null) {
try {
if (controller == oname) {
Registry.getRegistry(null, null).unregisterComponent(oname);
if (log.isDebugEnabled())
log.debug("unregistering " + oname);
}
} catch (Throwable t) {
log.error("Error unregistering ", t);
}
}
if (parent != null) {
parent.removeChild(this);
}
// Stop our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
removeChild(children[i]);
}
}
threadStart()
负责启动容器的后台任务程序。
/**
* Start the background thread that will periodically check for session
* timeouts.
* 启动后台线程并定期检查session失效
*/
protected void threadStart() {
if (thread != null)
return;
if (backgroundProcessorDelay <= 0)
return;
threadDone = false;
String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
thread = new Thread(new ContainerBackgroundProcessor(), threadName);
thread.setDaemon(true);//后台程序
thread.start();
}
threadStop()
负责停止后台进程运行。
/**
* Stop the background thread that is periodically checking for session
* timeouts.
* 停止线程
*/
protected void threadStop() {
if (thread == null)
return;
threadDone = true;
thread.interrupt();//打断方式停止
try {
thread.join();
} catch (InterruptedException e) {
;
}
thread = null;
}
从上面的组件和方法可以看出,容器所需完成的功能或者说是所具备的功能有:
说好的坚持,总是断断续续