zoukankan      html  css  js  c++  java
  • Tomcat 8(九)解读Tomcat组件的生命周期(Lifecycle)

    Tomcat 8(七)解读Bootstrap介绍过。运行startup.bat。将引发Tomcat一连串组件的启动。事实上这一连串启动是通过组件的生命周期(Lifecycle)实现的

    今天来看看Lifecycle设计。解读Lifecycle。涉及到例如以下几个类

    Lifecycle、LifecycleState、LifecycleEvent、LifecycleListener(位于org.apache.catalina)

    LifecycleBase、LifecycleSupport、LifecycleMBeanBase(位于org.apache.catalina.util)

    Lifecycle接口

    package org.apache.catalina;
    
    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;
    
        public LifecycleState getState();
    
        public String getStateName();
    }

    Lifecycle接口的作用

    定义了事件类型(静态常量字符串)

    定义了init/start/stop/destroy方法,即组件初始化/启动/停止/销毁

    定义了addLifecycleListener/findLifecycleListeners/removeLifecycleListener方法,即加入/获取/移除监听器(监听器主要监听启动、停止动作)

    LifecycleState枚举

    package org.apache.catalina;
    
    public enum LifecycleState {
        NEW(false, null),
        INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),
        INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),
        STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),
        STARTING(true, Lifecycle.START_EVENT),
        STARTED(true, Lifecycle.AFTER_START_EVENT),
        STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),
        STOPPING(false, Lifecycle.STOP_EVENT),
        STOPPED(false, Lifecycle.AFTER_STOP_EVENT),
        DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),
        DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),
        FAILED(false, null),
        MUST_STOP(true, null),
        MUST_DESTROY(false, null);
    
        private final boolean available;
        private final String lifecycleEvent;
    
        private LifecycleState(boolean available, String lifecycleEvent) {
            this.available = available;
            this.lifecycleEvent = lifecycleEvent;
        }
    
        public boolean isAvailable() {
            return available;
        }
    
        public String getLifecycleEvent() {
            return lifecycleEvent;
        }
    }

    LifecycleState定义了组件状态的枚举。LifecycleState包括两个属性:available、lifecycleEvent

    available(boolean)-处于此状态的组件能否够运行public方法(get/set方法除外)。能否够获取lifecycleEvent值

    lifecycleEvent(String)-处于此状态的组件正进行的事件

    LifecycleEvent

    LifecycleEvent是个实体类,包括三个属性lifecycle、type、data

    lifecycle(Lifecycle)-将触发事件的组件

    (注意:每一个组件都能够向上转成Lifecycle类型。由于组件继承LifecycleMBeanBase。而LifecycleMBeanBase继承LifecycleBase,而LifecycleBase是Lifecycle的一种实现)

    type(String)-事件类型

    data(String)-事件数据

    LifecycleSupport

    LifecycleSupport将组件正在进行的LifecycleEvent通知给监听器(LifecycleListener)

    LifecycleListener

    监听特定事件。并做出对应处理

    AprLifecycleListener(org.apache.catalina.core)就是LifecycleListener的一种实现

    组件更新状态时,假设组件当前状态的lifecycleEvent不为空。LifecycleSupport会将 lifecycleEvent通知给LifecycleListenerLifecycleListener会做出对应处理 

    LifecycleBase

    LifecycleBase实现了Lifecycle接口,加入了几个新的方法如setStateInternal(更新组件状态)fireLifecycleEvent(触发LifecycleEvent)

    加入了四个抽象方法initInternal、startInternal、stopInternal、destroyInternal

    LifecycleBase内初始化了LifecycleSupport、LifecycleState

    private final LifecycleSupport lifecycle = new LifecycleSupport(this);
    private volatile LifecycleState state = LifecycleState.NEW;

    以下来看看LifecycleBase的init方法的逻辑(start/stop/destroy的逻辑与init类似)

    public final synchronized void init() throws LifecycleException {
    	//查看组件状态是否为LifecycleState.NEW
    	if (!state.equals(LifecycleState.NEW)) {
    		invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
    	}
    	//更新组件状态LifecycleState.INITIALIZING
    	setStateInternal(LifecycleState.INITIALIZING, null, false);
    
    	try {
    	//调用initInternal
    		initInternal();
    	} catch (Throwable t) {
    		ExceptionUtils.handleThrowable(t);
    		setStateInternal(LifecycleState.FAILED, null, false);
    		throw new LifecycleException(
    				sm.getString("lifecycleBase.initFail",toString()), t);
    	}
    	
    	//更新组件状态为LifecycleState.INITIALIZED。

    到此初始化完毕 setStateInternal(LifecycleState.INITIALIZED, null, false); }

    注意init方法内部又调用了initInternal方法

    LifecycleMBeanBase

    LifecycleMBeanBase继承LifecycleBase,LifecycleMBeanBase内又加入了一些新的方法

    StandardServerStandardService等组件继承LifecycleMBeanBase,并重写initInternalstartInternalstopInternaldestroyInternal方法

    以下来看看StandardServer的initInternal方法

    protected void initInternal() throws LifecycleException {
    	//调用父类(LifecycleMBeanBase)的initInternal方法
    	super.initInternal();
    	
    	onameStringCache = register(new StringCache(), "type=StringCache");
    
    	// Register the MBeanFactory
    	MBeanFactory factory = new MBeanFactory();
    	factory.setContainer(this);
    	onameMBeanFactory = register(factory, "type=MBeanFactory");
    
    	// Register the naming resources
    	globalNamingResources.init();
    
    	// Populate the extension validator with JARs from common and shared
    	// class loaders
    	if (getCatalina() != null) {
    		ClassLoader cl = getCatalina().getParentClassLoader();
    		// Walk the class loader hierarchy. Stop at the system class loader.
    		// This will add the shared (if present) and common class loaders
    		while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
    			if (cl instanceof URLClassLoader) {
    				URL[] urls = ((URLClassLoader) cl).getURLs();
    				for (URL url : urls) {
    					if (url.getProtocol().equals("file")) {
    						try {
    							File f = new File (url.toURI());
    							if (f.isFile() &&
    									f.getName().endsWith(".jar")) {
    								ExtensionValidator.addSystemResource(f);
    							}
    						} catch (URISyntaxException e) {
    							// Ignore
    						} catch (IOException e) {
    							// Ignore
    						}
    					}
    				}
    			}
    			cl = cl.getParent();
    		}
    	}
    	//Server调用其子组件(Service)的init方法,Service在初始化过程中又会调用其子组件的init方法
    	for (int i = 0; i < services.length; i++) {
    		services[i].init();
    	}
    }

    Catalina调用StandardServer的init方法时,因为StandardServer未重写init方法,因此将使用LifecycleBase的init方法。当运行到initInternal()时,因为StandardServer重写了initInternal方法,因此将使用StandardServer的initInternal方法(应用了多态。每一个组件的initInternal方法包括其自己定义逻辑)

    通过Lifecycle。Tomcat启动最顶层组件(Server)。就可以启动全部组件

     

  • 相关阅读:
    Active Directory如何用C#进行增加、删除、修改、查询用户与组织单位!
    showModalDialog和showModelessDialog的使用
    如何在GridView中使用DataFromatString
    GridView/DataGrid单元格不换行的问题
    要Gmail、Orkut邀请的请留下你的邮箱
    How to reset security settings back to the defaults
    ASP.NET 2.0 学习笔记 1: session 与 script 应用
    关闭主窗体而不退出主程序 以及如何获取操作系统的关闭、注销信息
    ASP.NET 2.0 学习笔记 2: 页面间传值
    Windows 系统常用设置方法与技巧
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7306453.html
Copyright © 2011-2022 走看看