Tomcat笔记(三)

Tomcat笔记(三)

来看看 ContainerBase start 方法:
 1 public   synchronized   void  start()  throws  LifecycleException  {
 2
 3        //如果Container已经处于start状态,直接返回
 4        if (started) {
 5            if(log.isInfoEnabled())
 6                log.info(sm.getString("containerBase.alreadyStarted", logName()));
 7            return;
 8        }

 9        
10        // Notify our interested LifecycleListeners
11        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
12
13        started = true;
14
15        // Start our subordinate components, if any
16        if ((loader != null&& (loader instanceof Lifecycle))
17            ((Lifecycle) loader).start();
18        logger = null;
19        getLogger();
20        if ((logger != null&& (logger instanceof Lifecycle))
21            ((Lifecycle) logger).start();
22    //用来管理session
23        if ((manager != null&& (manager instanceof Lifecycle))
24            ((Lifecycle) manager).start();
25    //看名字就知道是干什么的,不过研究集群的优先级很低
26        if ((cluster != null&& (cluster instanceof Lifecycle))
27            ((Lifecycle) cluster).start();
28    //用来进行访问控制,或者权限控制的
29        if ((realm != null&& (realm instanceof Lifecycle))
30            ((Lifecycle) realm).start();
31    //和JNDI相关
32        if ((resources != null&& (resources instanceof Lifecycle))
33            ((Lifecycle) resources).start();
34
35        //启动所有子container
36        Container children[] = findChildren();
37        for (int i = 0; i < children.length; i++{
38            if (children[i] instanceof Lifecycle)
39                ((Lifecycle) children[i]).start();
40        }

41
42        // 启动Container内部持有的pipeline对象,Container对Pipeline接口的实现就是通过调用这个内部持有的Pipeline对象
43        if (pipeline instanceof Lifecycle)
44            ((Lifecycle) pipeline).start();
45
46        // Notify our interested LifecycleListeners
47        lifecycle.fireLifecycleEvent(START_EVENT, null);
48
49        // 注释说这个函数用来check session是否过期,但看的不是太懂
50        threadStart();
51
52        // Notify our interested LifecycleListeners
53        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
54
55}

56
 

所有和clusterrealm相关都放在最后来研究了,不管怎么样先把tomcat如何处理request的整个过程串起来对现在的我来说是最重要的。另外还有Tomcat中的很多部件都用到了JMX API,即SNMPJava实现来进行性能检测和管理,这个也会放在最后研究。

ContainerBase就看这么多了,下面来看看StandardEngine这个类。除去和clusterrealmJMX相关的方法后,StanderdEngine剩下的方法就很很少了。

StandardEngine有一个Service类型的成员。Java doc中指出Service就是由很多共享同一个ContainerConnector组成。一个Service对应于一个Container,来自这个Service的任何一个Connectorrequest都会由其对应的Container进行处理。看到现在的感觉就是ConnectorContainer提供request对象,并接受Container返回的response对象。在Tomcat中有很多类别都被用来体现现request或者response,例如org.apache.catalina.connector .Request就是Coyote request的一个wrapper类,Coyote这个framework帮助封装了底层的网络复杂性,向上提供一个统一的接口。我想tomcat既能够成为一个standalonehttpjsp/Servlet服务器,也能够同apache http server集成,很可能就是依赖于Coyote提供的统一接口。

在构造函数中会将 StandardEngine 这个 Pipeline 的最后一个 Valve ,即 Basic 设置为 StandardEngineValve 。来看看 StandardEnginValue invoke 方法
 1 public   final   void  invoke(Request request, Response response)
 2          throws  IOException, ServletException  {
 3
 4        // Select the Host to be used for this Request
 5        Host host = request.getHost();
 6        if (host == null{
 7            response.sendError
 8                (HttpServletResponse.SC_BAD_REQUEST,
 9                 sm.getString("standardEngine.noHost"
10                              request.getServerName()));
11            return;
12        }

13
14        // Ask this Host to process this request
15        host.getPipeline().getFirst().invoke(request, response);
16
17    }

18
 

可以看出在处理到StandardEngine这个Pipeline的最后一个Valve时,会根据当前request所指定的Host,将当前的requestresponse传递给该Host这个Pipeline的第一个Valve进行处理。

我想Tomcat中的EngineHostContextWrapper处理request生成response的过程大概是这样的:

Engine 在收到 request 后在其 Pipeline 中的每一个 Valve request 进行处理,也可能会生成 response 的某些部分,在最后一个 Valve 中将 request response 传给下一级 Container Host 的第一个 Valve Host 重复同样过程,继续传递给 Context Context 再传递给 Wrapper 。由于 Wrapper 代表的是 Servlet 对象,因此在 Wrapper 处所有的处理都结束了, response 对象生成完毕。当然了,如果在某一级中无法找到 request 要求的下一级对象,则整个处理过程也会立即结束。

你可能感兴趣的:(Tomcat笔记(三))