Tomcat架构设计-容器组件基类

2019-08-14  本文已影响0人  贪睡的企鹅

1 Tomcat核心功能

2 Tomcat总体架构设计

通过tomcat功能可以将Tomcat设计了两个核心组件连接器(Connector)和容器(Container)来分别来处理对外交流,内部处理。

image

Tomcat中一个容器可能对接多个连接器,每一个连接器都对应某种协议某种IO模型,tomcat将单个容器和多个连接器组成一个service组件,一个tomcat中可能存在多个Service组件

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 应用。

image
3.2 Container中核心组件

tomcat 将Container容器按功能分为4个组件,分别是 Engine、Host、Context 和 Wrapper。这 4 种容器不是平行关系,而是父子关系。

image

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

image
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);
}

image

4 ContainerBase

有了接口,我们就要用类去实现接口。一般来说实现类不止一个,不同的类在实现接口时往往会有一些相同的逻辑,如果让各个子类都去实现一遍,就会有重复代码。那子类如何重用这部分逻辑呢?其实就是定义一个基类来实现共同的逻辑,然后让各个子类去继承它,就达到了重用的目的。

Tomcat 定义一个基类ContainerBase来实现Container接口,把一些公共的逻辑放到基类中去.其中包括如下功能:

4.1 通用容器组件

基类ContainerBase中定义容器组件所依赖的一些通用组件。

[图片上传失败...(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组件调用容器组件处理完后调用记录日志。

image

同步处理调用

    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);
    }
上一篇 下一篇

猜你喜欢

热点阅读