• 浅读tomcat架构设计之tomcat生命周期(2)


      浅读tomcat架构设计和tomcat启动过程(1)

      https://www.cnblogs.com/piaomiaohongchen/p/14977272.html

      tomcat通过org.apache.catalina.Lifecycle接口统一管理生命周期,所有有生命周期的组建都要实现Lifecycle接口.

      通过反射加载查看代码:

      Lifecycle的接口方法有很多,简单解读下:  

      (1)定义13个String类型的常量,不同的常量,代表不同的状态信息

      

      (2)定义了3个管理监听器的方法:

      分别是添加,监听和删除

        void addLifecycleListener(LifecycleListener var1);
    
        LifecycleListener[] findLifecycleListeners();
    
        void removeLifecycleListener(LifecycleListener var1);

      

      

      (3)定义了四个生命周期方法:

        分别是初始化,开启,停止,销毁:

    void init() throws LifecycleException;
    
    void start() throws LifecycleException;
    
    void stop() throws LifecycleException;
    
    void destroy() throws LifecycleException;

      

      (4)定义了获取状态的两个方法:

    LifecycleState getState();
    
    String getStateName();

      

       其中getState的返回类是enum类型,getStateName返回的类型是String类型

      Lifecycle接口的默认实现是org.apache.catalina.util.LifecycleBase,LifecycleBase为Lifecycle里的接口方法提供了默认实现.

      先看看三个管理监听器方法的具体实现:

      org.apache.catalina.util.LifecycleBase:   

       public void addLifecycleListener(LifecycleListener listener) {
            this.lifecycle.addLifecycleListener(listener);
        }
    
        public LifecycleListener[] findLifecycleListeners() {
            return this.lifecycle.findLifecycleListeners();
        }
    
        public void removeLifecycleListener(LifecycleListener listener) {
            this.lifecycle.removeLifecycleListener(listener);
        }

      发现在方法内部都是调用的lifecycle.**()方法

      而this.lifecycle的定义是

        

     private final LifecycleSupport lifecycle = new LifecycleSupport(this);

        

      三个监听器方法都是调用的是LifecycleSupport类的对象方法

      LifecycleSupport监听器是通过一个数组属性listeners来保存的,代码如下:

      org.apache.catalina.util.LifecycleSupport:

    private final Object listenersLock = new Object();
    
        public LifecycleSupport(Lifecycle lifecycle) {
            this.lifecycle = lifecycle;
        }
    
        public void addLifecycleListener(LifecycleListener listener) {
            synchronized(this.listenersLock) {
                LifecycleListener[] results = new LifecycleListener[this.listeners.length + 1];
    
                for(int i = 0; i < this.listeners.length; ++i) {
                    results[i] = this.listeners[i];
                }
    
                results[this.listeners.length] = listener;
                this.listeners = results;
            }
        }
    
        public LifecycleListener[] findLifecycleListeners() {
            return this.listeners;
        }
    
        public void fireLifecycleEvent(String type, Object data) {
            LifecycleEvent event = new LifecycleEvent(this.lifecycle, type, data);
            LifecycleListener[] interested = this.listeners;
    
            for(int i = 0; i < interested.length; ++i) {
                interested[i].lifecycleEvent(event);
            }
    
        }
    
        public void removeLifecycleListener(LifecycleListener listener) {
            synchronized(this.listenersLock) {
                int n = -1;
    
                for(int i = 0; i < this.listeners.length; ++i) {
                    if (this.listeners[i] == listener) {
                        n = i;
                        break;
                    }
                }
    
                if (n >= 0) {
                    LifecycleListener[] results = new LifecycleListener[this.listeners.length - 1];
                    int j = 0;
    
                    for(int i = 0; i < this.listeners.length; ++i) {
                        if (i != n) {
                            results[j++] = this.listeners[i];
                        }
                    }
    
                    this.listeners = results;
                }
            }
        }

      这三个方法的实现非常简单,就是新增/删除/查找等动作的实现,就是对listener属性做操作

        其中的fireLifecycleEvent函数的含义是用于遍历所有监听器进行处理  

        

      

      四个生命周期的方法:

        先看init方法,让我们回到之前的org.apache.catalina.util.LifecycleBase类:

        org.apache.catalina.util.LifecycleBase:

        

    public final synchronized void init() throws LifecycleException {
            if (!this.state.equals(LifecycleState.NEW)) {
                this.invalidTransition("before_init");
            }
    
            this.setStateInternal(LifecycleState.INITIALIZING, (Object)null, false);
    
            try {
                this.initInternal();
            } catch (Throwable var2) {
                ExceptionUtils.handleThrowable(var2);
                this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
                throw new LifecycleException(sm.getString("lifecycleBase.initFail", new Object[]{this.toString()}), var2);
            }
    
            this.setStateInternal(LifecycleState.INITIALIZED, (Object)null, false);
        }

      代码很简单,就是先判断state是否是LifecycleState.NEW,如果是NEW的话就设置为state状态为LifecycleState.INITIALIZING,如果不是,就抛出异常,所以init初始化的时候必须是LifecycleState.NEW

      接着往下看,看start方法:

         

    public final synchronized void start() throws LifecycleException {
            if (!LifecycleState.STARTING_PREP.equals(this.state) && !LifecycleState.STARTING.equals(this.state) && !LifecycleState.STARTED.equals(this.state)) {
                if (this.state.equals(LifecycleState.NEW)) {
                    this.init();
                } else if (this.state.equals(LifecycleState.FAILED)) {
                    this.stop();
                } else if (!this.state.equals(LifecycleState.INITIALIZED) && !this.state.equals(LifecycleState.STOPPED)) {
                    this.invalidTransition("before_start");
                }
    
                this.setStateInternal(LifecycleState.STARTING_PREP, (Object)null, false);
    
                try {
                    this.startInternal();
                } catch (Throwable var2) {
                    ExceptionUtils.handleThrowable(var2);
                    this.setStateInternal(LifecycleState.FAILED, (Object)null, false);
                    throw new LifecycleException(sm.getString("lifecycleBase.startFail", new Object[]{this.toString()}), var2);
                }
    
                if (!this.state.equals(LifecycleState.FAILED) && !this.state.equals(LifecycleState.MUST_STOP)) {
                    if (!this.state.equals(LifecycleState.STARTING)) {
                        this.invalidTransition("after_start");
                    }
    
                    this.setStateInternal(LifecycleState.STARTED, (Object)null, false);
                } else {
                    this.stop();
                }
    
            } else {
                if (log.isDebugEnabled()) {
                    Exception e = new LifecycleException();
                    log.debug(sm.getString("lifecycleBase.alreadyStarted", new Object[]{this.toString()}), e);
                } else if (log.isInfoEnabled()) {
                    log.info(sm.getString("lifecycleBase.alreadyStarted", new Object[]{this.toString()}));
                }
    
            }
        }

      start方法做的事情比int方法多一些,判断state状态,如果是LifecycleState.NEW,就初始化,根据不同的state状态,进不同的逻辑,然后设置状态调用setStateInternal方法:

        跟进方法:

        还是在org.apache.catalina.util.LifecycleBase:

    private synchronized void setStateInternal(LifecycleState state, Object data, boolean check) throws LifecycleException {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("lifecycleBase.setState", new Object[]{this, state}));
            }
    
            if (check) {
                if (state == null) {
                    this.invalidTransition("null");
                    return;
                }
    
                if (state != LifecycleState.FAILED && (this.state != LifecycleState.STARTING_PREP || state != LifecycleState.STARTING) && (this.state != LifecycleState.STOPPING_PREP || state != LifecycleState.STOPPING) && (this.state != LifecycleState.FAILED || state != LifecycleState.STOPPING)) {
                    this.invalidTransition(state.name());
                }
            }
    
            this.state = state;
            String lifecycleEvent = state.getLifecycleEvent();
            if (lifecycleEvent != null) {
                this.fireLifecycleEvent(lifecycleEvent, data);
            }
    
        }

      这个方法先是判断check,然后判断state是否为null,是null就抛出异常,最后将state赋值给state变量,然后调用getLifecycleEvent方法处理事件,下面的this.fireLifecycleEvent(lifecycleEvent, data);实际上调用的是LifecycleSupport类的方法:

      跟进这个方法看下:

        

     protected void fireLifecycleEvent(String type, Object data) {
            this.lifecycle.fireLifecycleEvent(type, data);
        }

       继续往上回溯:

      

     private final LifecycleSupport lifecycle = new LifecycleSupport(this);

      同理stop和destroy方法逻辑类似

      获取状态的两个方法  

      还是在org.apache.catlina.util.LifecycleBase:

      在生命周期的相应方法中获取state属性,直接返回的state

      

    public LifecycleState getState() {
            return this.state;
        }
    
        public String getStateName() {
            return this.getState().toString();
        }

        

        

  • 相关阅读:
    又学到的2个小技巧
    CSS3 简写animation
    CSS3 区别Transform,Transition,Animation一句话
    纠错【2012年5月9日 JQuery跑马灯(文字无缝向上翻动)(自已封装的第三个插件)】
    jQuery计算选中的文本字数,并弹出一个层(插件四)
    html5Canvas绘制线条closePath();
    html5循环方式绘制矩形
    jQuery过滤not()与filter();
    javascript在firebug调试时用console.log
    jQuery插件在光标定位的地方插入文字(插件5)
  • 原文地址:https://www.cnblogs.com/piaomiaohongchen/p/14982770.html
Copyright © 2020-2023  润新知