乔乔lovefreedom

导航

tomcat源码剖析

最近看Tomcat的源码的节奏还算是挺紧凑的,给人的感觉,tomcat的代码相对以前读的jetty的代码显得更有条理一些。。。当然这也是有可能是因为自己看的jetty的版本是比较老的,而看的Tomcat的代码却是比较新的Tomcat8的代码。。。。

好了闲话不多说了。。。

先来说说LifeCycle的概念。。。

这个在jetty中也有,组要是用于维护一个组件的生命周期,例如start,stop啥的。。。

另外对于有lifecycle概念的组件,一般也都还有listener的概念,当组件的状态发生改变的时候,可以有listener进行响应。。。

好啦先来看看最上层的LifeCycle接口的定义吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//生命周期的接口定义
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。。。这里就拿初始化的方法来举例子吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   //这里扩展了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类型,其实这里看名字就能够知道这个抽象层要干些啥事情了吧。。。。来看一段代码:

1
2
3
4
5
6
7
8
9
10
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部分的内容吧。。。首先来看看最顶层的接口的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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上面去的。。。

由于它的代码比较长,这里就不直接贴出来了。。来比较重要的属性定义吧:

1
2
private Service services[] = new Service[0];   //用于保存所有的service,是一个数组啊
private final Object servicesLock = new Object();

 

嗯,一个service的数组。。。。嗯,容器嘛。。。

 

好了,这里也就稍微的来看看初始话和启动两个方法的实现吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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的初始化,另外还有一些其他的操作,注释应该也算是交代的比较清楚吧。。。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//父类中定义的抽象方法扩展了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();
        }
    }
}

启动方法,这里其实最主要的也还是对Service的启动。。。

posted on 2015-04-09 17:51  乔乔lovefreedom  阅读(287)  评论(0编辑  收藏  举报