美文网首页Tomcat
Tomcat中设计模式-模板模式

Tomcat中设计模式-模板模式

作者: 晴天哥_王志 | 来源:发表于2018-12-01 20:48 被阅读67次

    开篇

     模板方法模式抽象出某个业务操作公共的流程,将流程分为几个步骤,其中有一些步骤是固定不变的,有一些步骤是变化的,固定不变的步骤通过一个基类来实现,而变化的部分通过钩子方法让子类去实现,这样就实现了对系统中流程的统一化规范化管理。

     Tomcat中关于生命周期管理的地方很好应用了模板方法模式,在一个组件的生命周期中都会涉及到init(初始化),start(启动),stop(停止),destory(销毁),而对于每一个生命周期阶段其实都有固定一些事情要做,比如判断前置状态,设置后置状态,以及通知状态变更事件的监听者等,而这些工作其实是可以固化的,所以Tomcat中就将每个生命周期阶段公共的部分固化,然后通过initInternal,startInternal,stopInternal,destoryInternal这几个钩子方法开放给子类去实现具体的逻辑。

    源码分析

    说明:

    • 1.tomcat的所有容器都实现了Lifecycle的生命周期管理接口,这里以Tomcat几个核心组件为例。
    • 2.抽象基类LifecycleBase实现Lifecycle接口,在基类当中实现了模板接口start、stop、init等方法接口。

    源码部分

    public interface Lifecycle {
    
        public static final String BEFORE_INIT_EVENT = "before_init";
        public static final String AFTER_INIT_EVENT = "after_init";
        public static final String START_EVENT = "start";
        public static final String BEFORE_START_EVENT = "before_start";
        public static final String AFTER_START_EVENT = "after_start";
        public static final String STOP_EVENT = "stop";
        public static final String BEFORE_STOP_EVENT = "before_stop";
        public static final String AFTER_STOP_EVENT = "after_stop";
        public static final String AFTER_DESTROY_EVENT = "after_destroy";
        public static final String BEFORE_DESTROY_EVENT = "before_destroy";
        public static final String PERIODIC_EVENT = "periodic";
        public static final String CONFIGURE_START_EVENT = "configure_start";
        public static final String CONFIGURE_STOP_EVENT = "configure_stop";
    
        public void addLifecycleListener(LifecycleListener listener);
        public LifecycleListener[] findLifecycleListeners();
        public void removeLifecycleListener(LifecycleListener listener);
        public void init() throws LifecycleException;
        public void start() throws LifecycleException;
        public void stop() throws LifecycleException;
        public void destroy() throws LifecycleException;
    }
    

    说明:

      1. 基类LifecycleBase实现了Lifecycle接口并实现init、start、stop、destroy等方法。
      1. init()方法内部模板化初始化流程,抽象具体的实现initInternal()方法。
      1. start()方法内部模板化启动流程,抽象具体的实现startInternal()方法。
      1. stop()方法内部模板化停止流程,抽象具体的实现stopInternal()方法。
      1. destroy()方法内部模板化释放流程,抽象具体的实现destroyInternal()方法。
    public abstract class LifecycleBase implements Lifecycle {
    
        private static final Log log = LogFactory.getLog(LifecycleBase.class);
        private static final StringManager sm = StringManager.getManager(LifecycleBase.class);
        private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
    
    
        private volatile LifecycleState state = LifecycleState.NEW;
    
        public void addLifecycleListener(LifecycleListener listener) {
            lifecycleListeners.add(listener);
        }
    
        public LifecycleListener[] findLifecycleListeners() {
            return lifecycleListeners.toArray(new LifecycleListener[0]);
        }
    
        public void removeLifecycleListener(LifecycleListener listener) {
            lifecycleListeners.remove(listener);
        }
    
        protected void fireLifecycleEvent(String type, Object data) {
            LifecycleEvent event = new LifecycleEvent(this, type, data);
            for (LifecycleListener listener : lifecycleListeners) {
                listener.lifecycleEvent(event);
            }
        }
    
        public final synchronized void init() throws LifecycleException {
            if (!state.equals(LifecycleState.NEW)) {
                invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
            }
    
            try {
                setStateInternal(LifecycleState.INITIALIZING, null, false);
                initInternal();
                setStateInternal(LifecycleState.INITIALIZED, null, false);
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
                setStateInternal(LifecycleState.FAILED, null, false);
                throw new LifecycleException(
                        sm.getString("lifecycleBase.initFail",toString()), t);
            }
        }
    
    
        protected abstract void initInternal() throws LifecycleException;
    
        public final synchronized void start() throws LifecycleException {
    
            if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                    LifecycleState.STARTED.equals(state)) {
    
                if (log.isDebugEnabled()) {
                    Exception e = new LifecycleException();
                    log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
                } else if (log.isInfoEnabled()) {
                    log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
                }
    
                return;
            }
    
            if (state.equals(LifecycleState.NEW)) {
                init();
            } else if (state.equals(LifecycleState.FAILED)) {
                stop();
            } else if (!state.equals(LifecycleState.INITIALIZED) &&
                    !state.equals(LifecycleState.STOPPED)) {
                invalidTransition(Lifecycle.BEFORE_START_EVENT);
            }
    
            try {
                setStateInternal(LifecycleState.STARTING_PREP, null, false);
                startInternal();
                if (state.equals(LifecycleState.FAILED)) {
                    stop();
                } else if (!state.equals(LifecycleState.STARTING)) {
                    invalidTransition(Lifecycle.AFTER_START_EVENT);
                } else {
                    setStateInternal(LifecycleState.STARTED, null, false);
                }
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
                setStateInternal(LifecycleState.FAILED, null, false);
                throw new LifecycleException(sm.getString("lifecycleBase.startFail", toString()), t);
            }
        }
    
        protected abstract void startInternal() throws LifecycleException;
    
        public final synchronized void stop() throws LifecycleException {
    
            if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) ||
                    LifecycleState.STOPPED.equals(state)) {
    
                if (log.isDebugEnabled()) {
                    Exception e = new LifecycleException();
                    log.debug(sm.getString("lifecycleBase.alreadyStopped", toString()), e);
                } else if (log.isInfoEnabled()) {
                    log.info(sm.getString("lifecycleBase.alreadyStopped", toString()));
                }
    
                return;
            }
    
            if (state.equals(LifecycleState.NEW)) {
                state = LifecycleState.STOPPED;
                return;
            }
    
            if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {
                invalidTransition(Lifecycle.BEFORE_STOP_EVENT);
            }
    
            try {
                if (state.equals(LifecycleState.FAILED)) {
                    fireLifecycleEvent(BEFORE_STOP_EVENT, null);
                } else {
                    setStateInternal(LifecycleState.STOPPING_PREP, null, false);
                }
    
                stopInternal();
    
                if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {
                    invalidTransition(Lifecycle.AFTER_STOP_EVENT);
                }
    
                setStateInternal(LifecycleState.STOPPED, null, false);
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
                setStateInternal(LifecycleState.FAILED, null, false);
                throw new LifecycleException(sm.getString("lifecycleBase.stopFail",toString()), t);
            } finally {
                if (this instanceof Lifecycle.SingleUse) {
                    // Complete stop process first
                    setStateInternal(LifecycleState.STOPPED, null, false);
                    destroy();
                }
            }
        }
    
        protected abstract void stopInternal() throws LifecycleException;
    
    
        @Override
        public final synchronized void destroy() throws LifecycleException {
            if (LifecycleState.FAILED.equals(state)) {
                try {
                    // Triggers clean-up
                    stop();
                } catch (LifecycleException e) {
                    // Just log. Still want to destroy.
                    log.warn(sm.getString(
                            "lifecycleBase.destroyStopFail", toString()), e);
                }
            }
    
            if (LifecycleState.DESTROYING.equals(state) ||
                    LifecycleState.DESTROYED.equals(state)) {
    
                if (log.isDebugEnabled()) {
                    Exception e = new LifecycleException();
                    log.debug(sm.getString("lifecycleBase.alreadyDestroyed", toString()), e);
                } else if (log.isInfoEnabled() && !(this instanceof Lifecycle.SingleUse)) {
                    log.info(sm.getString("lifecycleBase.alreadyDestroyed", toString()));
                }
    
                return;
            }
    
            if (!state.equals(LifecycleState.STOPPED) &&
                    !state.equals(LifecycleState.FAILED) &&
                    !state.equals(LifecycleState.NEW) &&
                    !state.equals(LifecycleState.INITIALIZED)) {
                invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT);
            }
    
            try {
                setStateInternal(LifecycleState.DESTROYING, null, false);
                destroyInternal();
                setStateInternal(LifecycleState.DESTROYED, null, false);
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
                setStateInternal(LifecycleState.FAILED, null, false);
                throw new LifecycleException(
                        sm.getString("lifecycleBase.destroyFail",toString()), t);
            }
        }
    
    
        protected abstract void destroyInternal() throws LifecycleException;
    }
    

    招聘信息

    【招贤纳士】

    欢迎热爱技术、热爱生活的你和我成为同事,和贝贝共同成长。

    贝贝集团诚招算法、大数据、BI、Java、PHP、android、iOS、测试、运维、DBA等人才,有意可投递zhi.wang@beibei.com

    贝贝集团创建于2011年,旗下拥有贝贝网、贝店、贝贷等平台,致力于成为全球领先的家庭消费平台。

    贝贝创始团队来自阿里巴巴,先后获得IDG资本、高榕资本、今日资本、新天域资本、北极光等数亿美金的风险投资。

    公司地址:杭州市江干区普盛巷9号东谷创业园(上下班有多趟班车)

    相关文章

      网友评论

        本文标题:Tomcat中设计模式-模板模式

        本文链接:https://www.haomeiwen.com/subject/twgrcqtx.html