Container容器-tomcat6.x源码阅读

2013-09-21java

容器是tomcat的基础,tomcat经过容器来管理和维护tomcat组件,最外层的容器是Server,最内层的容器是Wrapper,容器提供了一些基础的功能,例如添加父容器,子容器,共享数据,数据隔离等。web

Container
Container是tomcat中的容器接口,定义了容器所具备的方法和tomcat中容器的规范。容器接口提供了操做容器的方法,例如设置父容器和添加子容器,查找容器,添加监听容器事件的监听器,是invoke(Request, Response)处理HTTP协议请求的方法。apache

ContainerBase
ContainerBase是Container接口的基本实现,是个抽象类,在类中提供了Container大多数方法的实现,把一些容器公共实现抽象到ContainerBase实现。ContainerBase的功能是:实现了Container接口的大多数方法,把子类所须要实现的共同方法在基类中实现,避免在子类中重复编码,子类经过继承ContainerBase类来完成。数组

LifecycleSupport
ContainerBase抽象类中的属性,Lifecycle接口实现类,功能是负责管理注册在容器上面的LifecycleEvent监听类,监听容器的生命周期变动,集中管理监听器。tomcat

listeners
ContainerBase的属性,容器监听器数组,用户监听容器自己事件,监听的是ContainerEvent事件,与LifecycleEvent不一样。安全

Loader
ContainerBase的属性,tomcat本身封装的类加载器,针对webapp安全的类加载,管理webapp的类加载,在java的类加载器体系中,不一样类加载器加载的类实例是不能同时访问的。session

Manager
ContainerBase的属性,Manager是用来管理在容器上面的Session池,负责Session的生命周期,从生成到销毁,Manager是一个管理Session池的一个方法集合接口。app

cluster : Cluster
ContainerBase的属性,跟集群有关。webapp

pipeline : Pipeline
ContainerBase的属性,很重要,是Valve链,功能是负责管理Valve,也是请求信息传递链,最终目的是ServletWrapper中。pipeline 决定Valve的顺序,控制请求信息,是容器间传递请求信息的桥梁。this

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()
负责容器的初始化工做,主要有一下几步,

  • 注册到MBeanServer
  • 标记已经初始化
/**
	 * 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()
负责容器的启动工做,主要有如下几步,主要启动添加在容器上面的组件。

  • 判断是否已经启动
  • 触发BEFORE_START_EVENT事件,标记已经启动
  • 启动类加载器loader,日志记录器logger,session管理器manager,集群节点cluster,权限管理器realm,目录资源服务resources
  • 启动子容器
  • 启动Valve链pipeline
  • 触发START_EVENT事件
  • 启动后台任务处理进程
  • 触发AFTER_START_EVENT事件
/**
	 * 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;

	}

从上面的组件和方法能够看出,容器所需完成的功能或者说是所具有的功能有:

  • 设置父容器,添加管理子容器
  • 管理Session
  • 权限管理
  • 后台任务处理
  • 生命周期事件监听
  • 属性变动事件监听
  • Valve链,过滤请求和响应信息

说好的坚持,老是断断续续

相关文章
相关标签/搜索