最近看Tomcat的源码的节奏还算是挺紧凑的,给人的感觉,tomcat的代码相对以前读的jetty的代码显得更有条理一些。。。当然这也是有可能是因为自己看的jetty的版本是比较老的,而看的Tomcat的代码却是比较新的Tomcat8的代码。。。。
好了闲话不多说了。。。
先来说说LifeCycle的概念。。。
这个在jetty中也有,组要是用于维护一个组件的生命周期,例如start,stop啥的。。。
另外对于有lifecycle概念的组件,一般也都还有listener的概念,当组件的状态发生改变的时候,可以有listener进行响应。。。
好啦先来看看最上层的LifeCycle接口的定义吧:
//生命周期的接口定义 public interface Lifecycle { //下面定义了一些基本的状态 public static final String BEFORE_INIT_EVENT = "before_init"; /** * The LifecycleEvent type for the "component after init" event. */ public static final String AFTER_INIT_EVENT = "after_init"; /** * The LifecycleEvent type for the "component start" event. */ public static final String START_EVENT = "start"; /** * The LifecycleEvent type for the "component before start" event. */ public static final String BEFORE_START_EVENT = "before_start"; /** * The LifecycleEvent type for the "component after start" event. */ public static final String AFTER_START_EVENT = "after_start"; /** * The LifecycleEvent type for the "component stop" event. */ public static final String STOP_EVENT = "stop"; /** * The LifecycleEvent type for the "component before stop" event. */ public static final String BEFORE_STOP_EVENT = "before_stop"; /** * The LifecycleEvent type for the "component after stop" event. */ public static final String AFTER_STOP_EVENT = "after_stop"; /** * The LifecycleEvent type for the "component after destroy" event. */ public static final String AFTER_DESTROY_EVENT = "after_destroy"; /** * The LifecycleEvent type for the "component before destroy" event. */ public static final String BEFORE_DESTROY_EVENT = "before_destroy"; /** * The LifecycleEvent type for the "periodic" event. */ 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 Methods /** * Add a LifecycleEvent listener to this component. * * @param listener The listener to add */ //添加一个监听器 public void addLifecycleListener(LifecycleListener listener); /** * Get the life cycle listeners associated with this life cycle. If this * component has no listeners registered, a zero-length array is returned. */ //返回所有的监听器 public LifecycleListener[] findLifecycleListeners(); /** * Remove a LifecycleEvent listener from this component. * * @param listener The listener to remove */ //移除一个监听器 public void removeLifecycleListener(LifecycleListener listener); //初始化 public void init() throws LifecycleException; //启动 public void start() throws LifecycleException; //停止 public void stop() throws LifecycleException; /** * Prepare to discard the object. The following {@link LifecycleEvent}s will * be fired in the following order: * <ol> * <li>DESTROY_EVENT: On the successful completion of component * destruction.</li> * </ol> * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ //销毁 public void destroy() throws LifecycleException; /** * Obtain the current state of the source component. * * @return The current state of the source component. */ //返回当前的生命周期状态 public LifecycleState getState(); /** * Obtain a textual representation of the current component state. Useful * for JMX. */ //返回状态的名字 public String getStateName(); }
还是比较简单的吧,先是一些基本的状态和事件的定义,然后接下来是一些基本的操作,例如添加listener,移除listener,启动,停止什么的。。都还算比较的常规。。。
接下来是LifeCycle的抽象层,LifecycleBase。。。
这里就不具体的体贴出它的实现代码了,。。。LifecycleBase直接继承自LifeCycle接口,这里主要是实现了中间添加listener,移除listener的操作,这里可以可以初步理解为这里扩展成了一个listener的容器。。
另外LifecycleBase的定义中,还扩展了基本的启动,停止操作什么的。。。
例如当组件启动的时候,就需要更改当前组件的状态,并调用相应的listener。。。这里就拿初始化的方法来举例子吧:
//这里扩展了init方法,这里首先设置当前组件的状态, @Override public final synchronized void init() throws LifecycleException { if (!state.equals(LifecycleState.NEW)) { invalidTransition(Lifecycle.BEFORE_INIT_EVENT); } setStateInternal(LifecycleState.INITIALIZING, null, false); //设置当前的状态为INITIALIZING try { initInternal(); //调用该方法用于初始化,具体的实现在子类中 } catch (Throwable t) { ExceptionUtils.handleThrowable(t); setStateInternal(LifecycleState.FAILED, null, false); throw new LifecycleException( sm.getString("lifecycleBase.initFail",toString()), t); } setStateInternal(LifecycleState.INITIALIZED, null, false); //将对象设置为INITIALIZED状态 } //具体初始化的方法啊,在子类中实现 protected abstract void initInternal() throws LifecycleException;
这里应该代码很容易能理解吧,无非就是对当前组件的装填进行验证,并修改组件的状态,当然在设置组件的状态的时候还伴随着对listener的调用。。。
最后再调用initInternal方法进行初始化,当然这个方法需要在具体的子类中进行实现。。。。
另外这里还要介绍一个比较特殊的LifeCycle的抽象层,LifecycleMBeanBase,它继承了抽象类LifecycleBase类型,其实这里看名字就能够知道这个抽象层要干些啥事情了吧。。。。来看一段代码:
protected void initInternal() throws LifecycleException { // If oname is not null then registration has already happened via // preRegister(). if (oname == null) { mserver = Registry.getRegistry(null, null).getMBeanServer(); //获取用到的mbserver oname = register(this, getObjectNameKeyProperties()); //注册当前组件到mbserver } }
嗯,其实就是在组件的初始化的时候对当前组件在JMX上进行注册,具体Tomcat的JMX部分内容,在前面的文章中就已经说过了,这里就不详细说了。。。
也就是说,如果一个类型需要在JMX上进行注册,那么它需要继承LifeCycleMBeanBase抽象类,然后实现其中的几个抽象方法。。。
好啦,到这里位置,LifeCycle部分的内容就算差不多了。。
总的感觉,Tomcat在LifeCycle部分的设计还算是比较简单的。。。。
好啦,接下来来看看Server部分的内容吧。。。首先来看看最顶层的接口的定义:
package org.apache.catalina; import java.io.File; import org.apache.catalina.deploy.NamingResourcesImpl; import org.apache.catalina.startup.Catalina; //顶层的server接口的定义,继承了生命周期接口 public interface Server extends Lifecycle { // ------------------------------------------------------------- Properties /** * Return the global naming resources. */ public NamingResourcesImpl getGlobalNamingResources(); /** * Set the global naming resources. * * @param globalNamingResources The new global naming resources */ public void setGlobalNamingResources (NamingResourcesImpl globalNamingResources); /** * Return the global naming resources context. */ public javax.naming.Context getGlobalNamingContext(); /** * Return the port number we listen to for shutdown commands. */ public int getPort(); //用于监听shutdown命令的端口 /** * Set the port number we listen to for shutdown commands. * * @param port The new port number */ public void setPort(int port); ////用于监听shutdown命令的端口 /** * Return the address on which we listen to for shutdown commands. */ public String getAddress(); //用于监听shutdown命令的地址 /** * Set the address on which we listen to for shutdown commands. * * @param address The new address */ public void setAddress(String address); //用于监听shutdown命令的地址 /** * Return the shutdown command string we are waiting for. */ public String getShutdown(); /** * Set the shutdown command we are waiting for. * * @param shutdown The new shutdown command */ public void setShutdown(String shutdown); public ClassLoader getParentClassLoader(); //这个server对象用的classLoader,一般是catalina loader public void setParentClassLoader(ClassLoader parent); public Catalina getCatalina(); //获取catalina对象 public void setCatalina(Catalina catalina); //设置用的catalina对象 public File getCatalinaBase(); //一般情况下都是tomcat的根路径 public void setCatalinaBase(File catalinaBase); public File getCatalinaHome(); public void setCatalinaHome(File catalinaHome); public void addService(Service service); //添加service对象 public void await(); public Service findService(String name); //根据名字获取某个service public Service[] findServices(); //获取所有的service public void removeService(Service service); //删除一个service }
嗯,其实最顶层的Server接口的定义也很简单,扩展了lifeCycle接口其中最重要的部分无非是对service的添加以及移除。。。
给人最大的干吼就是它是一个service的容器
好啦,接下来来看看最常用的类型StandardServer吧,这里它不光实现了Server接口,还继承了LifecycleMBeanBase类型,这里也就表示StandardServer将会被注册到JMX上面去的。。。
由于它的代码比较长,这里就不直接贴出来了。。来比较重要的属性定义吧:
private Service services[] = new Service[0]; //用于保存所有的service,是一个数组啊 private final Object servicesLock = new Object();
嗯,一个service的数组。。。。嗯,容器嘛。。。
好了,这里也就稍微的来看看初始话和启动两个方法的实现吧:
protected void initInternal() throws LifecycleException { super.initInternal(); //父类的init,它里面主要是进行对象在mbserver上面注册当前对象 // Register global String cache // Note although the cache is global, if there are multiple Servers // present in the JVM (may happen when embedding) then the same cache // will be registered under multiple names onameStringCache = register(new StringCache(), "type=StringCache"); // Register the MBeanFactory MBeanFactory factory = new MBeanFactory(); //创建MBeanFactory factory.setContainer(this); //设置当前mbeanfactory的container onameMBeanFactory = register(factory, "type=MBeanFactory"); //注册mbeanfactory // Register the naming resources globalNamingResources.init(); //初始计划名字资源 // Populate the extension validator with JARs from common and shared // class loaders if (getCatalina() != null) { //获取catalina对象 ClassLoader cl = getCatalina().getParentClassLoader(); //在bootstrap里面设置成了shareloader // Walk the class loader hierarchy. Stop at the system class loader. // This will add the shared (if present) and common class loaders //加载classLoader里面的路径的资源,这里会向上遍历classLoader 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(); } } // Initialize our defined Services for (int i = 0; i < services.length; i++) { //初始化service services[i].init(); } }
首先是初始化,这里最重要的事情其实是对当前包含的所有的service的初始化,另外还有一些其他的操作,注释应该也算是交代的比较清楚吧。。。
//父类中定义的抽象方法扩展了lifecycle的start方法,用于启动当前的对象,这里月就是启动tomcat,其实是启动server的service @Override protected void startInternal() throws LifecycleException { fireLifecycleEvent(CONFIGURE_START_EVENT, null); setState(LifecycleState.STARTING); globalNamingResources.start(); // Start our defined Services synchronized (servicesLock) { for (int i = 0; i < services.length; i++) { //遍历当前的service,然后启动他们 services[i].start(); } } }
好了,到这里,Server大体的东西就这些吧,其实干货不多。。。
干活最多的地方应该在Connector部分,不过这个以后再写吧。。。。。
Tomcat源码分析之Server与Lifecycle的设计与实现,布布扣,bubuko.com
Tomcat源码分析之Server与Lifecycle的设计与实现
原文:http://blog.csdn.net/fjslovejhl/article/details/20300179