1 Tomcat核心功能
- 处理 Socket 连接,负责网络字节流与 Request 和 Response 对象相互转化。
- 加载和管理 Servlet,以及具体处理 Request 请求。
2 Tomcat总体架构设计
通过tomcat功能可以将Tomcat设计了两个核心组件连接器(Connector)和容器(Container)来分别来处理对外交流,内部处理。

Tomcat中一个容器可能对接多个连接器,每一个连接器都对应某种协议某种IO模型,tomcat将单个容器和多个连接器组成一个service组件,一个tomcat中可能存在多个Service组件
-
Connector:将不同协议不同IO模型的请求转换为标准的标准的 ServletRequest 对象交给容器处理。
-
Container:负责servelt的加载和管理,处理请求,并返回标准的 ServletResponse 对象给连接器。
3 Container容器设计
Container本质上是一个Servlet容器,负责servelt的加载和管理,处理请求ServletRequest,并返回标准的 ServletResponse 对象给连接器。
3.1 核心功能
按照servlet规范我们可以将多个servelt打包一个war包,而这个war包就表示一个web应用程序,war名称就是应用程序的名称。一个一个网站来说会存在多个域名,每个域名则会对应多个web应用程序。
例如有一个网购系统,有面向网站管理人员的后台管理系统,还有面向终端客户的在线购物系统。这两个系统跑在同一个 Tomcat 上,为了隔离它们的访问域名,配置了两个虚拟域名:manage.shopping.com和user.shopping.com,网站管理人员通过manage.shopping.com域名访问 Tomcat 去管理用户和商品,而用户管理和商品管理是两个单独的 Web 应用。终端客户通过user.shopping.com域名去搜索商品和下订单,搜索功能和订单管理也是两个独立的 Web 应用。

3.2 Container中核心组件
tomcat 将Container容器按功能分为4个组件,分别是 Engine、Host、Context 和 Wrapper。这 4 种容器不是平行关系,而是父子关系。
-
Wrapper:表示一个 Servlet
-
Context:表示一个 Web 应用程序,一个 Web 应用程序中可能会有多个 Servlet
-
Host:表示的是一个虚拟主机,或者说一个站点,可以给 Tomcat 配置多个虚拟主机地址,而一个虚拟主机下可以部署多个 Web 应用程序
-
Engine:表示引擎,用来管理多个虚拟站点,一个 Service 最多只能有一个 Engine。

可以再通过 Tomcat 的server.xml配置文件来加深对 Tomcat 容器的理解。Tomcat 采用了组件化的设计,它的构成组件都是可配置的,其中最外层的是 Server,其他组件按照一定的格式要求配置在这个顶层容器中。

3.3 组件类图
Container容器中定义了Container 接口用来描述Container容器中所有的组件,不同的子组件分别定义了不同子接口做描述。容器组件之间具有父子关系。
public interface Container extends Lifecycle {
public void setName(String name);
public Container getParent();
public void setParent(Container container);
public void addChild(Container child);
public void removeChild(Container child);
public Container findChild(String name);
}

4 ContainerBase
有了接口,我们就要用类去实现接口。一般来说实现类不止一个,不同的类在实现接口时往往会有一些相同的逻辑,如果让各个子类都去实现一遍,就会有重复代码。那子类如何重用这部分逻辑呢?其实就是定义一个基类来实现共同的逻辑,然后让各个子类去继承它,就达到了重用的目的。
Tomcat 定义一个基类ContainerBase来实现Container接口,把一些公共的逻辑放到基类中去.其中包括如下功能:
4.1 通用容器组件
基类ContainerBase中定义容器组件所依赖的一些通用组件。
-
Cluster(集群):负责实现多个tomcat容器集群功能,其中包括对多个tomcat jvm进程相互通信,会话同步。
-
Realm(认证): 负责存储用户,密码及权限等数据对象,配合tomcat实现资源认证。不同的容器对应不同级别的Realm,不同级别表示用户认指的范围大小不同。
-
AccessLog(访问日志):负责客户端请求访问的日志的记录。
-
log(日志):负责不同级别的日志输出。
-
Pipline(管道):Pipline是责任链的设计模式,么一个容器组件都对应着一个管道,tomcat将不同层级的容器管道串联起来处理请求,每个容器管理可以自由维护Value来对请求处理实现动态扩展。
[图片上传失败...(image-85a445-1565753384145)]
4.1.1 通用组件属性定义
/**
* log组件
*/
protected Log logger = null;
/**
* 关联的log名称
*/
protected String logName = null;
/**
* 当前容器组件对应cluster组件
*/
protected Cluster cluster = null;
/**
* 集群对象CLuster读写锁
*/
private final ReadWriteLock clusterLock = new ReentrantReadWriteLock();
/**
* 当前容器组件对应的的Realm组件
*/
private volatile Realm realm = null;
/**
* 当前容器组件对应的Realm组件读写锁
*/
private final ReadWriteLock realmLock = new ReentrantReadWriteLock();
/**
* 当前容器组件对应的pipeline组件
*/
protected final Pipeline pipeline = new StandardPipeline(this);
/**
* 当前容器组件对应的AccessLog组件
*/
protected volatile AccessLog accessLog = null;
/**
* 获取AccessLog组件时
* 如果accessLogScanComplete为false
* 对AccessLog组件初始化(扫描pipeline组件中类型为AccessLog的Value,添加到AccessLog组件)
*/
private volatile boolean accessLogScanComplete = false;
4.1.2 log组件相关方法
@Override
public Log getLogger() {
if (logger != null)
return (logger);
logger = LogFactory.getLog(getLogName());
return (logger);
}
@Override
public String getLogName() {
if (logName != null) {
return logName;
}
String loggerName = null;
Container current = this;
while (current != null) {
String name = current.getName();
if ((name == null) || (name.equals(""))) {
name = "/";
} else if (name.startsWith("##")) {
name = "/" + name;
}
loggerName = "[" + name + "]"
+ ((loggerName != null) ? ("." + loggerName) : "");
current = current.getParent();
}
logName = ContainerBase.class.getName() + "." + loggerName;
return logName;
}
4.1.3 pipeline组件相关方法
@Override
public Pipeline getPipeline() {
return (this.pipeline);
}
4.1.4 Realm组件相关方法
@Override
public Realm getRealm() {
Lock l = realmLock.readLock();
l.lock();
try {
if (realm != null)
return (realm);
if (parent != null)
return (parent.getRealm());
return null;
} finally {
l.unlock();
}
}
protected Realm getRealmInternal() {
Lock l = realmLock.readLock();
l.lock();
try {
return realm;
} finally {
l.unlock();
}
}
@Override
public void setRealm(Realm realm) {
Lock l = realmLock.writeLock();
l.lock();
try {
/** 获取当前组件绑定的Realm组件对象引用设置给oldRealm **/
Realm oldRealm = this.realm;
if (oldRealm == realm)
return;
this.realm = realm;
/** 如果当前组件处于运行状态,则停止oldRealm组件 **/
if (getState().isAvailable() && (oldRealm != null) &&
(oldRealm instanceof Lifecycle)) {
try {
((Lifecycle) oldRealm).stop();
} catch (LifecycleException e) {
log.error("ContainerBase.setRealm: stop: ", e);
}
}
/** 将新设置Realm组件和当前组件对象反相关联 **/
if (realm != null)
realm.setContainer(this);
/** 如果当前组件处于运行状态,启动新设置realm组件 **/
if (getState().isAvailable() && (realm != null) &&
(realm instanceof Lifecycle)) {
try {
((Lifecycle) realm).start();
} catch (LifecycleException e) {
log.error("ContainerBase.setRealm: start: ", e);
}
}
/** 触发属性变更 **/
support.firePropertyChange("realm", oldRealm, this.realm);
} finally {
l.unlock();
}
}
4.1.5 cluster组件相关方法
@Override
public Cluster getCluster() {
Lock readLock = clusterLock.readLock();
readLock.lock();
try {
if (cluster != null)
return cluster;
if (parent != null)
return parent.getCluster();
return null;
} finally {
readLock.unlock();
}
}
protected Cluster getClusterInternal() {
Lock readLock = clusterLock.readLock();
readLock.lock();
try {
return cluster;
} finally {
readLock.unlock();
}
}
@Override
public void setCluster(Cluster cluster) {
Cluster oldCluster = null;
Lock writeLock = clusterLock.writeLock();
writeLock.lock();
try {
/** 获取当前组件原始Cluster组件对象引用设置给oldCluster **/
oldCluster = this.cluster;
if (oldCluster == cluster)
return;
this.cluster = cluster;
/** 如果当前组件还在运行,则停止oldCluster组件 **/
if (getState().isAvailable() && (oldCluster != null) &&
(oldCluster instanceof Lifecycle)) {
try {
((Lifecycle) oldCluster).stop();
} catch (LifecycleException e) {
log.error("ContainerBase.setCluster: stop: ", e);
}
}
/** 将新设置cluster组件和当前容器组件对象反相关联 **/
if (cluster != null)
cluster.setContainer(this);
/** 如果当前组件处于运行状态,启动新设置cluster组件 **/
if (getState().isAvailable() && (cluster != null) &&
(cluster instanceof Lifecycle)) {
try {
((Lifecycle) cluster).start();
} catch (LifecycleException e) {
log.error("ContainerBase.setCluster: start: ", e);
}
}
} finally {
writeLock.unlock();
}
/** 触发属性变更 **/
support.firePropertyChange("cluster", oldCluster, cluster);
}
4.1.6 AccessLog组件相关方法
基类ContainerBase中定义使用AccessLog组件打印日志方法logAccess,在调用getAccessLog()方法获取AccessLog组件时如果accessLogScanComplete为false,需要对AccessLog组件实例化,其实现类为AccessLogAdapter适配器,其内部维护一个类型为AccessLog的数组,在实例化AccessLogAdapter后会同步扫描Pipeline组件中类型为AccessLog的阀门,添加到AccessLogAdapter适配器类型为AccessLog的数组中。
/**
* 使用getAccessLog方法获取AccessLog组件打印日志,
* 如果当前组件不存在AccessLog组件则使用父容器组绑定AccessLog组件打印日志。
*/
@Override
public void logAccess(Request request, Response response, long time,
boolean useDefault) {
boolean logged = false;
/** 使用AccessLog组件打印日志 **/
if (getAccessLog() != null) {
getAccessLog().log(request, response, time);
logged = true;
}
/** 使用父容器AccessLog组件打印日志 **/
if (getParent() != null) {
getParent().logAccess(request, response, time, (useDefault && !logged));
}
}
/**
* 获取AccessLog组件时
* 如果accessLogScanComplete为false,需要对AccessLog组件实例化,
* 其实现类为AccessLogAdapter适配器,其内部维护一个类型为AccessLog的数组,
* 实例化同步扫描Pipeline组件中类型为AccessLog的阀门,添加到AccessLogAdapter适配器类型为AccessLog的数组中
*/
@Override
public AccessLog getAccessLog() {
if (accessLogScanComplete) {
return accessLog;
}
AccessLogAdapter adapter = null;
Valve valves[] = getPipeline().getValves();
for (Valve valve : valves) {
if (valve instanceof AccessLog) {
if (adapter == null) {
adapter = new AccessLogAdapter((AccessLog) valve);
} else {
adapter.add((AccessLog) valve);
}
}
}
if (adapter != null) {
accessLog = adapter;
}
accessLogScanComplete = true;
return accessLog;
}
public class AccessLogAdapter implements AccessLog {
private AccessLog[] logs;
public AccessLogAdapter(AccessLog log) {
Objects.requireNonNull(log);
logs = new AccessLog[] { log };
}
public void add(AccessLog log) {
Objects.requireNonNull(log);
AccessLog newArray[] = Arrays.copyOf(logs, logs.length + 1);
newArray[newArray.length - 1] = log;
logs = newArray;
}
@Override
public void log(Request request, Response response, long time) {
for (AccessLog log: logs) {
log.log(request, response, time);
}
}
@Override
public void setRequestAttributesEnabled(boolean requestAttributesEnabled) {
// NOOP
}
@Override
public boolean getRequestAttributesEnabled() {
// NOOP. Could return logs[0].getRequestAttributesEnabled(), but I do
// not see a use case for that.
return false;
}
}
这里logAccess方法通常是在CoyoteAdapter组件调用容器组件处理完后调用记录日志。

同步处理调用
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
throws Exception {
...省略代码
long time = System.currentTimeMillis() - req.getStartTime();
if (context != null) {
context.logAccess(request, response, time, false);
} else if (response.isError()) {
if (host != null) {
host.logAccess(request, response, time, false);
} else {
connector.getService().getContainer().logAccess(
request, response, time, false);
}
}
...省略代码
异步处理调用
@Override
public boolean asyncDispatch(org.apache.coyote.Request req, org.apache.coyote.Response res,
SocketEvent status) throws Exception {
// Access logging
if (!success || !request.isAsync()) {
long time = 0;
if (req.getStartTime() != -1) {
time = System.currentTimeMillis() - req.getStartTime();
}
Context context = request.getContext();
if (context != null) {
context.logAccess(request, response, time, false);
} else {
log(req, res, time);
}
}
}
4.2 容器事件监听器
4.2.1 监听器列表定义
/**
* 容器事件监听器
*/
protected final List<ContainerListener> listeners = new CopyOnWriteArrayList<>();
4.2.1 监听器维护
/**
* 添加容器事件监听器
*/
@Override
public void addContainerListener(ContainerListener listener) {
listeners.add(listener);
}
/**
* 删除容器事件监听器
*/
@Override
public void removeContainerListener(ContainerListener listener) {
listeners.remove(listener);
}
/**
* 获取所有容器事件监听器
*/
@Override
public ContainerListener[] findContainerListeners() {
ContainerListener[] results =
new ContainerListener[0];
return listeners.toArray(results);
}
4.2.2 容器事件触发
/**
* 处理容器事件
*/
@Override
public void fireContainerEvent(String type, Object data) {
if (listeners.size() < 1){
return;
}
ContainerEvent event = new ContainerEvent(this, type, data);
for (ContainerListener listener : listeners) {
listener.containerEvent(event);
}
}
4.3 属性变更处理器
4.3.1 属性变更处理器定义
/**
* 属性变更处理器
*/
protected final PropertyChangeSupport support =
new PropertyChangeSupport(this);
4.3.2 维护处理器中监听器
/**
* 添加属性变更监听器
*/
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
support.addPropertyChangeListener(listener);
}
/**
* 删除属性变更监听器
*/
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
support.removePropertyChangeListener(listener);
}
4.4 子容器组件的维护
4.4.1 子容器组件集合定义
/**
* 存储子容器的Map,key表示容器的名称,value表示容器组件对象
*/
protected final HashMap<String, Container> children = new HashMap<>();
4.4.1 子容器组件维护
/**
* 查找指定名称的子容器
*/
@Override
public Container findChild(String name) {
if (name == null) {
return null;
}
synchronized (children) {
return children.get(name);
}
}
/**
* 获取所有子容器组件
*/
@Override
public Container[] findChildren() {
synchronized (children) {
Container results[] = new Container[children.size()];
return children.values().toArray(results);
}
}
/**
* 为当前容器组件添加子容器组件
*/
@Override
public void addChild(Container child) {
if (Globals.IS_SECURITY_ENABLED) {
PrivilegedAction<Void> dp =
new PrivilegedAddChild(child);
AccessController.doPrivileged(dp);
} else {
addChildInternal(child);
}
}
/**
* 为当前容器组件添加子容器组件内部实现
*/
private void addChildInternal(Container child) {
if( log.isDebugEnabled() ){
log.debug("Add child " + child + " " + this);
}
/** 将添加的子容器和当前对象反相关联 **/
synchronized(children) {
if (children.get(child.getName()) != null){
throw new IllegalArgumentException("addChild: Child name '" +
child.getName() +
"' is not unique");
}
child.setParent(this); // May throw IAE
children.put(child.getName(), child);
}
/** 如果当前容器状态为运行,则启动添加的子容器 **/
try {
if ((getState().isAvailable() ||
LifecycleState.STARTING_PREP.equals(getState())) &&
startChildren) {
child.start();
}
} catch (LifecycleException e) {
log.error("ContainerBase.addChild: start: ", e);
throw new IllegalStateException("ContainerBase.addChild: start: " + e);
} finally {
/** 触发ContainerEvent事件ADD_CHILD_EVENT **/
fireContainerEvent(ADD_CHILD_EVENT, child);
}
}
/**
* 删除子容器组件
*/
@Override
public void removeChild(Container child) {
if (child == null) {
return;
}
/** 停止要删除的子容器组件 **/
try {
if (child.getState().isAvailable()) {
child.stop();
}
} catch (LifecycleException e) {
log.error("ContainerBase.removeChild: stop: ", e);
}
/** 如果删除的子容器组件停止后状态不等于LifecycleState.DESTROYING,则尝试销毁要删除的子容器组件 **/
try {
if (!LifecycleState.DESTROYING.equals(child.getState())) {
child.destroy();
}
} catch (LifecycleException e) {
log.error("ContainerBase.removeChild: destroy: ", e);
}
/** 将删除的子容器组件从当前容器的children Map类型的属性中删除 **/
synchronized(children) {
if (children.get(child.getName()) == null)
return;
children.remove(child.getName());
}
/** 触发ContainerEvent事件REMOVE_CHILD_EVENT **/
fireContainerEvent(REMOVE_CHILD_EVENT, child);
}
4.5 生命状态的转变与维护
4.5.1 初始化容器组件
ContainerBase扩展了initInternal实现,核心功能是实例化一个线程池来异步处理子容器的启动和停止。
/**
* 处理子容器启动关闭线程池核心线程数。
*/
private int startStopThreads = 1;
/**
* 处理子容器启动关闭线程池
*/
protected ThreadPoolExecutor startStopExecutor;
/**
* 组件初始化模板实现
*/
@Override
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();
}
@Override
public int getStartStopThreads() {
return startStopThreads;
}
private int getStartStopThreadsInternal() {
int result = getStartStopThreads();
if (result > 0) {
return result;
}
result = Runtime.getRuntime().availableProcessors() + result;
if (result < 1) {
result = 1;
}
return result;
}
private static class StartStopThreadFactory implements ThreadFactory {
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public StartStopThreadFactory(String namePrefix) {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
this.namePrefix = namePrefix;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(group, r, namePrefix + threadNumber.getAndIncrement());
thread.setDaemon(true);
return thread;
}
}
4.5.2 启动容器组件
ContainerBase扩展了startInternal实现,核心功能是对容器组件启动过程中首先启动依赖的通用组件。并使用线程池异步启动子容器。最后启动周期性任务线程处理。
/**
* 当前容器组件对应cluster组件
*/
protected Cluster cluster = null;
/**
* 当前容器组件对应的的Realm组件
*/
private volatile Realm realm = null;
/**
* 当前容器组件对应的AccessLog组件
*/
protected volatile AccessLog accessLog = null;
/**
* 组件启动模板实现
*/
@Override
protected synchronized void startInternal() throws LifecycleException {
logger = null;
/** 初始化日志组件 **/
getLogger();
/** 启动Cluster组件**/
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).start();
}
/** 启动Realm组件**/
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).start();
}
/** 使用线程池异步处理子容器启动 **/
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
results.add(startStopExecutor.submit(new StartChild(children[i])));
}
MultiThrowable multiThrowable = null;
/** 等待所有子容器启动完毕 **/
for (Future<Void> result : results) {
try {
result.get();
} catch (Throwable e) {
log.error(sm.getString("containerBase.threadedStartFailed"), e);
if (multiThrowable == null) {
multiThrowable = new MultiThrowable();
}
multiThrowable.add(e);
}
}
if (multiThrowable != null) {
throw new LifecycleException(sm.getString("containerBase.threadedStartFailed"),
multiThrowable.getThrowable());
}
/** 启动pipeline组件**/
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).start();
}
/** 设置当前容器的状态LifecycleState.STARTING **/
setState(LifecycleState.STARTING);
/** 启动线程,定时处理当前容器的所有子容器内backgroundProcess方法 **/
threadStart();
}
4.5.3 停止容器组件
ContainerBase扩展了stopInternal实现,核心功能是首先停止周期性任务线程处理,之后停止依赖的通用组件。并使用线程池异步停止子容器。
/**
* 组件停止模板实现
*/
@Override
protected synchronized void stopInternal() throws LifecycleException {
/** 关闭处理定时任务线程 **/
threadStop();
/** 设置当前容器的状态LifecycleState.STOPPING **/
setState(LifecycleState.STOPPING);
/** 停止pipeline组件**/
if (pipeline instanceof Lifecycle &&
((Lifecycle) pipeline).getState().isAvailable()) {
((Lifecycle) pipeline).stop();
}
/** 使用线程池异步处理子容器关闭 **/
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
results.add(startStopExecutor.submit(new StopChild(children[i])));
}
/** 等待所有子容器关闭完毕 **/
boolean fail = false;
for (Future<Void> result : results) {
try {
result.get();
} catch (Exception e) {
log.error(sm.getString("containerBase.threadedStopFailed"), e);
fail = true;
}
}
if (fail) {
throw new LifecycleException(
sm.getString("containerBase.threadedStopFailed"));
}
/** 关闭Realm组件**/
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).stop();
}
/** 关闭Cluster组件**/
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).stop();
}
}
4.5.3 销毁容器组件
ContainerBase扩展了destroyInternal实现,核心功能是销毁依赖的通用组件和子容器,并关闭线程池。
/**
* 组件销毁模板实现
*/
@Override
protected void destroyInternal() throws LifecycleException {
/** 销毁Realm组件**/
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).destroy();
}
/** 销毁cluster组件**/
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).destroy();
}
/** 销毁cluster组件**/
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).destroy();
}
/** 清空所有子容器 **/
for (Container child : findChildren()) {
removeChild(child);
}
/** 父容器和当前容器组件取消关联 **/
if (parent != null) {
parent.removeChild(this);
}
/** 关闭处理子容器启动关闭线程池 **/
if (startStopExecutor != null) {
startStopExecutor.shutdownNow();
}
super.destroyInternal();
}
4.6 周期性任务
4.6.1 相关属性定义
/**
* 定时任务处理线程对象
*/
private Thread thread = null;
/**
* 标识定时任务处理线程退出标识
*/
private volatile boolean threadDone = false;
/**
* 当前组件的定执行backgroundProcessor间隔间
*/
protected int backgroundProcessorDelay = -1;
4.6.2 启动停止周期任务
周期性任务停止通过threadDone这个标识来管控。
/**
* 启动线程,定时处理当前容器的所有子容器内backgroundProcess方法
*/
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();
}
/**
* 关闭处理定时任务线程
*/
protected void threadStop() {
if (thread == null){
return;
}
threadDone = true;
thread.interrupt();
try {
thread.join();
} catch (InterruptedException e) {
}
thread = null;
}
4.6.2 周期任务执行线程
周期任务执行就是调用调用当前容器以及子孙容器组件backgroundProcess方法。
/**
* 定时任务处理线程对象
*/
protected class ContainerBackgroundProcessor implements Runnable {
@Override
public void run() {
Throwable t = null;
String unexpectedDeathMessage = sm.getString(
"containerBase.backgroundProcess.unexpectedThreadDeath",
Thread.currentThread().getName());
try {
/** 间隔backgroundProcessorDelay时间,调用processChildren函数 **/
while (!threadDone) {
try {
Thread.sleep(backgroundProcessorDelay * 1000L);
} catch (InterruptedException e) {
// Ignore
}
if (!threadDone) {
processChildren(ContainerBase.this);
}
}
} catch (RuntimeException|Error e) {
t = e;
throw e;
} finally {
if (!threadDone) {
log.error(unexpectedDeathMessage, t);
}
}
}
/**
* 调用当前容器以及子孙容器组件backgroundProcess方法
*/
protected void processChildren(Container container) {
ClassLoader originalClassLoader = null;
try {
if (container instanceof Context) {
Loader loader = ((Context) container).getLoader();
// Loader will be null for FailedContext instances
if (loader == null) {
return;
}
originalClassLoader = ((Context) container).bind(false, null);
}
container.backgroundProcess();
Container[] children = container.findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i].getBackgroundProcessorDelay() <= 0) {
processChildren(children[i]);
}
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error("Exception invoking periodic operation: ", t);
} finally {
if (container instanceof Context) {
((Context) container).unbind(false, originalClassLoader);
}
}
}
}
4.6.2 backgroundProcess默认实现
/**
* 容器默认定时任务处理逻辑
*/
@Override
public void backgroundProcess() {
if (!getState().isAvailable())
return;
/** 调用Cluster组件backgroundProcess 方法 **/
Cluster cluster = getClusterInternal();
if (cluster != null) {
try {
cluster.backgroundProcess();
} catch (Exception e) {
log.warn(sm.getString("containerBase.backgroundProcess.cluster",
cluster), e);
}
}
/** 调用Realm组件backgroundProcess 方法 **/
Realm realm = getRealmInternal();
if (realm != null) {
try {
realm.backgroundProcess();
} catch (Exception e) {
log.warn(sm.getString("containerBase.backgroundProcess.realm", realm), e);
}
}
/** 调用pipeline组件中所有Value的backgroundProcess 方法 **/
Valve current = pipeline.getFirst();
while (current != null) {
try {
current.backgroundProcess();
} catch (Exception e) {
log.warn(sm.getString("containerBase.backgroundProcess.valve", current), e);
}
current = current.getNext();
}
fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null);
}
4.7 其他功能
/**
* 当前容器的名称
*/
protected String name = null;
/**
* 当前容器组件的父容器组件
*/
protected Container parent = null;
/**
* 父类加载器
*/
protected ClassLoader parentClassLoader = null;
@Override
public File getCatalinaBase() {
if (parent == null) {
return null;
}
return parent.getCatalinaBase();
}
@Override
public File getCatalinaHome() {
if (parent == null) {
return null;
}
return parent.getCatalinaHome();
}
@Override
public ClassLoader getParentClassLoader() {
if (parentClassLoader != null)
return (parentClassLoader);
if (parent != null) {
return (parent.getParentClassLoader());
}
return (ClassLoader.getSystemClassLoader());
}
@Override
public void setParentClassLoader(ClassLoader parent) {
ClassLoader oldParentClassLoader = this.parentClassLoader;
this.parentClassLoader = parent;
support.firePropertyChange("parentClassLoader", oldParentClassLoader,
this.parentClassLoader);
}
@Override
public Container getParent() {
return (parent);
}
@Override
public void setParent(Container container) {
Container oldParent = this.parent;
this.parent = container;
support.firePropertyChange("parent", oldParent, this.parent);
}
@Override
public String getName() {
return (name);
}
@Override
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException(sm.getString("containerBase.nullName"));
}
String oldName = this.name;
this.name = name;
support.firePropertyChange("name", oldName, this.name);
}
网友评论