- 浏览: 150070 次
- 性别:
- 来自: 北京
文章分类
最新评论
tomcat源码阅读
tomcat7源码 build eclipse
http://tomcat.apache.org/tomcat-7.0-doc/building.html
http://ss1.javaeye.com/category/85155
http://speed847.javaeye.com/blog/search?page=2&query=tomcat
http://asialee.javaeye.com/?page=1
http://hi.baidu.com/macula7/blog/category/Tomcat/index/1 全部译文
https://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/ Tomcat 设计模式分析
http://www.ibm.com/developerworks/cn/java/j-lo-tomcat2/ Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析
https://www.ibm.com/developerworks/cn/java/j-lo-servlet/Servlet 工作原理解析
http://www.ibm.com/developerworks/cn/java/j-lo-jetty/?cmp=dwskl&cpb=dw&ct=dwcon& Jetty 的工作原理以及与 Tomcat 的比较
http://www.ibm.com/developerworks/cn/java/l-from-tomact/index.html 从Tomcat中得到更多-Tomcat的源码分析
http://blog.csdn.net/wangchengsi/article/details/2973012 Tomcat连接器:Coyote框架
http://www.infoq.com/cn/articles/zh-tomcat-http-request-1
http://he-wen.iteye.com/blog/846829
连接器 HttpConnector
处理器 HttpProcessor
容器 Container
http://blog.csdn.net/wangchengsi/article/details/2966847 别人的阅读心得
system.in.read()方法的作用是从键盘读出一个字符,然后返回它的Unicode码。按下Enter结束输入
/---------------------------
目录
3章、连接器 35
4章、tomcat的默认连接器 58
5章、容器 76
6章、生命周期94
7章、日志系统 108
8章、加载器 118
9章、session管理 133
10章、Security
11章、StandardWrapper
12章、StandardContext
13章、Host and Engine
14章、Server and Service
15章、Digester
16章、Shutdown Hook
3/
Catalina 中有两个主要的模块:连接器和容器
-----------------------------------------
4/
4.1Tomcat 连接器是一个可以插入 servlet 容器的独立模块,已经存在相当多的连接器了,包 括Coyote, mod_jk, mod_jk2和mod_webapp
它等待前来的HTTP 请求,创建request
和 response 对象,然后把 request 和 response 对象传递给容器。连接器是通过调用接口
org.apache.catalina.Container 的 invoke 方法来传递 request 和 response 对象的
4.2在 invoke方法里边,容器加载 servlet,调用它的 service 方法,管理会话,记录出错日
志等等
4.3Tomcat连接器必须实现org.apache.catalina.Connector接口。在这个接口的众多方法中,
最重要的是 getContainer,setContainer, createRequest和 createResponse。
yxw
1、HttpConnector initialize() 调用一个ServeSocket的工厂方法创建ServerSocket
2、HttpConnector 的start() 创建了一个指定大小的HttpProcessor对象池
同时调用了HttpProcessor的start方法,HttpProcessor实现线程接口,也就是执行run()方法,run()调用await(),因为available = false,被wait()在while内等待自己被notifyAll
3、HttpConnector实现了线程接口,start被调用,也就是执行run()方法,run方法内 while循环, 等待(serverSocket.accept())http请求进来
4、请求进来,HttpProcessor processor = createProcessor();从对象池中返回,
执行HttpProcessor 的processor.assign(socket);并把socket传进去,
assign方法内
while (available) {}被跳过 #此时available=false
available = true;
5、notifyAll();唤醒第2步中的HttpProcessor实例的await()中被阻断的部分继续执行,await()返回socket,HttpProcessor的run方法内process(socket);
await()返回socket的同时
available = false;
notifyAll();
此时第4步assign(socket)方法内while (available) {}依然能被跳过,也就又可以接受新的http请求了
6、第5步内HttpProcessor的run方法内process(socket);执行完毕connector.recycle(this); HttpProcessor实例被放回连接器的实例池内
7、在第1步创建HttpConnector创建一个container
把容器set给连接器,在处理器的process方法中调用了容器的invoke方法,在容器的invoke方法中调用了servlet.service()
-------------------------
容器
所有的容器类都扩展自抽象类ContainerBase
1、
org.apache.catalina.Container接口定义了容器的形式,
有四种容器:Engine(引擎), Host(主机), Context(上下文), 和 Wrapper(包装器)
· Engine:表示整个Catalina的servlet引擎
· Host:表示一个拥有数个上下文的虚拟主机
· Context:表示一个Web应用,一个context包含一个或多个wrapper
· Wrapper:表示一个独立的servlet
一个容器可以有一个或多个低层次上的子容器
传递一个Container实例给Connector对象的setContainer方法,然后Connector对象就可以使用container 的invoke方法
2、Container
一个容器还包含一系列的部分如Lodder、 Loggee、 Manager、 Realm和Resources。
更有意思的是Container接口被设计成Tomcat管理员可以通过server.xml文件配置来决定其工作方式的模式。它通过一个pipeline(流水线)和一系列的阀门来实现
org.apache.catalina中四个相关的接口:Pipeline, Valve, ValveContext, 和 Contained。
Pipeline 流水线接口
Value 阀门接口
ValueContext 阀门上下文接口
Contained
一个pipeline包含了改容器要唤醒的所有任务。每一个阀门表示了一个特定的
任务。一个容器的流水线有一个基本的阀门,但是你可以添加任意你想要添加的
阀门。阀门的数目定义为添加的阀门的个数(不包括基本阀门)
如果你已经理解了servlet过滤器,那么流水线和它的阀门的工作方式不难想象。
一个流水线就像一个过滤链,每一个阀门像一个过滤器。跟过滤器一样,一个阀
门可以操作传递给它的request和response 方法。让一个阀门完成了处理,则
进一步处理流水线中的下一个阀门,基本阀门总是在最后才被调用。
一个容器可以有一个流水线。当容器的invoke方法被调用的时候,容器将会处
理流水线中的阀门,并一个接一个的处理,直到所有的阀门都被处理完毕
流水线必须保证说要添加给它的阀门必须被调用一次,流水线通过创建一
个ValveContext接口的实例来实现它。ValveContext是流水线的的内部类,这
样ValveContext就可以访问流水线中所有的成员。ValveContext中最重要的方
法是invokeNext方法:
3、Wrapper(包装器)
org.apache.catalina.Wrapper接口表示了一个包装器。一个包装器是表示一个
独立servlet定义的容器。包装器继承了Container接口,并且添加了几个方法。
包装器的实现类负责管理其下层servlet的生命中期,包括servlet的
init,service,和destroy方法。由于包装器是最底层的容器,所以不可以将子
容器添加给它。如果addChild方法被调用的时候会产生
IllegalArgumantException异常。
包装器接口中重要方法有allocate和load方法。allocate方法负责定位该包
装器表示的servlet的实例。Allocate方法必须考虑一个servlet是否实现了
avax.servlet.SingleThreadModel接口,该部分内容将会在 11 章中进行讨论。
Load方法负责load和初始化servlet的实例。
Mapper 接口
如何使用一个包含两个包装器的上下文来包装两个
servlet类。当有多于一个得包装器的时候,需要一个 map 来处理这些子容器,
对于特殊的请求可以使用特殊的子容器来处理
####################
容器的invoke()方法调用流水线接口pipeline的invoke方法
流水线通过创建一 个ValveContext 接口的实例来实现它。ValveContext 是流水线的的内部类,这
样ValveContext 就可以访问流水线中所有的成员。ValveContext 中最重要的方
法是 invokeNext方法:
public void invokeNext(Request request, Response response)
throws IOException, ServletException
流水线、阀门的设计很是精巧
1、HttpConnector connector = new HttpConnector();
Wrapper wrapper = new SimpleWrapper();
new连接器,
new包装器时,
public SimpleWrapper() {
pipeline.setBasic(new SimpleWrapperValve());
}
2、SimplePipeline pipeline = new SimplePipeline(this);
流水线Pipeline是包装器的属性类,new流水线时把包装器自己this当做一个容器传递进去
3、pipeline.setBasic(new SimpleWrapperValve());
把基本阀门SimpleWrapperValve setBasic()进去
public void setBasic(Valve valve) {
this.basic = valve;
((Contained) valve).setContainer(container);
}
此处的value其实是SimpleWrapperValve ,container是SimpleWrapper
4、set阀门
((Pipeline) wrapper).addValve(valve1);
((Pipeline) wrapper).addValve(valve2);
connector.setContainer(wrapper); 把包装器当做容器set给连接器
connector.initialize(); 连接器
connector.start();
处理器process(Socket socket)方法中调用容器的invoke方法,这一部分就是默认连接器的处理,请同上面的描述
connector.getContainer().invoke(request, response);
5、也就是调用SimpleWrapper这个包装器的invoke方法
public void invoke(Request request, Response response)
throws IOException, ServletException {
pipeline.invoke(request, response);
}
里面调用了SimplePipeline的invoke(request, response);方法
6、SimplePipeline的invoke(request, response)内
public void invoke(Request request, Response response)
throws IOException, ServletException {
// Invoke the first Valve in this pipeline for this request
(new SimplePipelineValveContext()).invokeNext(request, response);
}
SimplePipelineValveContext 是SimplePipeline的内部类
SimplePipelineValveContext 实现ValveContext接口(阀门上下文接口)
6、调用SimplePipelineValveContext的invokeNext(request, response)
public void invokeNext(Request request, Response response)
throws IOException, ServletException {
int subscript = stage;
stage = stage + 1;
// Invoke the requested Valve for the current request thread
if (subscript < valves.length) {
valves[subscript].invoke(request, response, this);
}
else if ((subscript == valves.length) && (basic != null)) {
basic.invoke(request, response, this);
}
else {
throw new ServletException("No valve");
}
}
} // end of inner class
if else 分别调用 3步设置的基本阀门 4步设置的日志、ip阀门
调用阀门的invoke(request, response, this);时把自己SimplePipelineValveContext传进去
再基本阀门中的调用SimplePipelineValveContext的invokeNext()方法形成类似递归的一个流水线调用
或者说是栈
###
可以使用 setBasic方法来分配一个基本阀门给流水线,getBasic方法会
得到基本阀门。最后被唤醒的基本阀门,负责处理request和回复response。
###
context 接口
一个 context在容器中表示一个web 应用。一个 context通常含有一个或多个包
装器作为其子容器。
重要的方法包括addWrapper, createWrapper 等方法
上下文 容器
--------------------------------------------
6、生命周期
一个实现了Lifecycle接口的组件同是会触发一个或多个下列事件:
BEFORE_START_EVENT, START_EVENT, AFTER_START_EVENT, BEFORE_STOP_EVENT,
STOP_EVENT, and AFTER_STOP_EVENT。当组件被启动的时候前三个事件会被触发,
而组件停止的时候会触发后边三个事件。另外,如果一个组件可以触发事件,那
么必须存在相应的监听器来对触发的事件作出回应。监听器使用
org.apache.catalina.LifecycleListener来表示
Lifecycle 中最重要的方法是start和 stop方法。一个组件提供了这些方法的
实现,所以它的父组件可以通过这些方法来启动和停止他们。另外3个方法
addLifecycleListener, findLifecycleListeners, 和
removeLifecycleListener 事跟监听器相关的类。组件的监听器对组件可能触发
的时间 “感兴趣”,当一个事件被触发的时候,相应监听器会被通知。一个
Lifecycle 实例可以触发使用静态最终字符串定义的六个事件。
LifeCycleEvent类 表示一个生命周期事件
LifeCycleListener接口 表示一个生命周期监听器
该接口中,只有一个方法 lifecycleEvent,该方法在事件触发的时候唤醒对
其 “感兴趣”的监听器
LifecycleSupport 类
connector.initialize();
((Lifecycle) connector).start();
((Lifecycle) context).start();
第5章时 只需要连接器start();
现在需要容器也start()
1、new SimpleContextLifecycleListener()
LifecycleListener listener = new SimpleContextLifecycleListener();
((Lifecycle) context).addLifecycleListener(listener);
2、容器的addLifecycleListener(listener);
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
3、容器实现了Lifecycle 生命周期接口
((Lifecycle) context).start();#显示调用
----------------------------------------
日志系统
FileLogger implements Lifecycle 实现了 生命周期接口
------------------------------
类加载器
一个 servlet容器需要一个定制的容器,而不是简单的使用系统的加
载器。如果像前面章节中那样使用系统的加载器来加载 servlet和其他需要的类,
这样 servlet就可以进入Java虚拟机CLASSPATH 环境下面的任何类和类库,这
会带来安全隐患。Servlet 只允许访问WEB-INF/目录及其子目录下面的类以及部
署在WEB-INF/lib 目录下的类库。
Tomcat 需要一个自己的加载器的另一个原因是它需要支持在WEB-INF/classes
或者是WEB-INF/lib 目录被改变的时候会重新加载。Tomcat 的加载器实现中使
用一个单独的线程来检查 servlet和支持类文件的时间戳。要支持类的自动加载
功能,一个加载器类必须实现org.apache.catalina.loader.Reloader接口
1、其中bootstrap类加载器用于引导 JVM,一旦调用java.exe程序,bootstrap
类加载器就开始工作。因此,它必须使用本地代码实现,然后加载 JVM 需要的类
到函数中。另外,它还负责加载所有的Java 核心类,例如 java.lang和 java.io
包。另外bootstrap类加载器还会查找核心类库如 rt.jar、i18n.jar等,这些
类库根据 JVM和操作系统来查找。
extension类加载器负责加载标准扩展目录下面的类。这样就可以使得编写程序
变得简单,只需把JAR 文件拷贝到扩展目录下面即可,类加载器会自动的在下面
查找。不同的供应商提供的扩展类库是不同的,Sun 公司的JVM 的标准扩展目录
是/jdk/jre/lib/ext。
system加载器是默认的加载器,它在环境变量CLASSPATH 目录下面查找相应的
类。
这样,JVM 使用哪个类加载器?答案在于委派模型(delegation model)
委派模型对于安全性是非常重要的
---------------------------------------------------------
13 Host和Engine
engine 表示了整个catalina 的servlet 引擎。engine 是处于最顶层的container。被添加到engine 的子
container 通常是org.apache.catalina.Host 或org.apache.catalina.Context。tomcat 默认是使用engine 的
-----------------------------------------------------------
14 Server与Service
在前面的章节中,已经说明了connector 和container 是如何工作的.在8080 端口上,只能有一个connector
服务于http 请求
org.apache.catalina.Server 接口表示了整个catalina 的servlet 引擎,囊括了所有的组件。server 使用一种
优雅的方法来启动/停止整个系统,不需要对connector 和container 分别启动/关闭
http://tomcat.apache.org/tomcat-7.0-doc/building.html
http://ss1.javaeye.com/category/85155
http://speed847.javaeye.com/blog/search?page=2&query=tomcat
http://asialee.javaeye.com/?page=1
http://hi.baidu.com/macula7/blog/category/Tomcat/index/1 全部译文
https://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/ Tomcat 设计模式分析
http://www.ibm.com/developerworks/cn/java/j-lo-tomcat2/ Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析
https://www.ibm.com/developerworks/cn/java/j-lo-servlet/Servlet 工作原理解析
http://www.ibm.com/developerworks/cn/java/j-lo-jetty/?cmp=dwskl&cpb=dw&ct=dwcon& Jetty 的工作原理以及与 Tomcat 的比较
http://www.ibm.com/developerworks/cn/java/l-from-tomact/index.html 从Tomcat中得到更多-Tomcat的源码分析
http://blog.csdn.net/wangchengsi/article/details/2973012 Tomcat连接器:Coyote框架
http://www.infoq.com/cn/articles/zh-tomcat-http-request-1
http://he-wen.iteye.com/blog/846829
连接器 HttpConnector
处理器 HttpProcessor
容器 Container
http://blog.csdn.net/wangchengsi/article/details/2966847 别人的阅读心得
system.in.read()方法的作用是从键盘读出一个字符,然后返回它的Unicode码。按下Enter结束输入
/---------------------------
目录
3章、连接器 35
4章、tomcat的默认连接器 58
5章、容器 76
6章、生命周期94
7章、日志系统 108
8章、加载器 118
9章、session管理 133
10章、Security
11章、StandardWrapper
12章、StandardContext
13章、Host and Engine
14章、Server and Service
15章、Digester
16章、Shutdown Hook
3/
Catalina 中有两个主要的模块:连接器和容器
-----------------------------------------
4/
4.1Tomcat 连接器是一个可以插入 servlet 容器的独立模块,已经存在相当多的连接器了,包 括Coyote, mod_jk, mod_jk2和mod_webapp
它等待前来的HTTP 请求,创建request
和 response 对象,然后把 request 和 response 对象传递给容器。连接器是通过调用接口
org.apache.catalina.Container 的 invoke 方法来传递 request 和 response 对象的
4.2在 invoke方法里边,容器加载 servlet,调用它的 service 方法,管理会话,记录出错日
志等等
4.3Tomcat连接器必须实现org.apache.catalina.Connector接口。在这个接口的众多方法中,
最重要的是 getContainer,setContainer, createRequest和 createResponse。
yxw
1、HttpConnector initialize() 调用一个ServeSocket的工厂方法创建ServerSocket
2、HttpConnector 的start() 创建了一个指定大小的HttpProcessor对象池
同时调用了HttpProcessor的start方法,HttpProcessor实现线程接口,也就是执行run()方法,run()调用await(),因为available = false,被wait()在while内等待自己被notifyAll
3、HttpConnector实现了线程接口,start被调用,也就是执行run()方法,run方法内 while循环, 等待(serverSocket.accept())http请求进来
4、请求进来,HttpProcessor processor = createProcessor();从对象池中返回,
执行HttpProcessor 的processor.assign(socket);并把socket传进去,
assign方法内
while (available) {}被跳过 #此时available=false
available = true;
5、notifyAll();唤醒第2步中的HttpProcessor实例的await()中被阻断的部分继续执行,await()返回socket,HttpProcessor的run方法内process(socket);
await()返回socket的同时
available = false;
notifyAll();
此时第4步assign(socket)方法内while (available) {}依然能被跳过,也就又可以接受新的http请求了
6、第5步内HttpProcessor的run方法内process(socket);执行完毕connector.recycle(this); HttpProcessor实例被放回连接器的实例池内
7、在第1步创建HttpConnector创建一个container
把容器set给连接器,在处理器的process方法中调用了容器的invoke方法,在容器的invoke方法中调用了servlet.service()
-------------------------
容器
所有的容器类都扩展自抽象类ContainerBase
1、
org.apache.catalina.Container接口定义了容器的形式,
有四种容器:Engine(引擎), Host(主机), Context(上下文), 和 Wrapper(包装器)
· Engine:表示整个Catalina的servlet引擎
· Host:表示一个拥有数个上下文的虚拟主机
· Context:表示一个Web应用,一个context包含一个或多个wrapper
· Wrapper:表示一个独立的servlet
一个容器可以有一个或多个低层次上的子容器
传递一个Container实例给Connector对象的setContainer方法,然后Connector对象就可以使用container 的invoke方法
2、Container
一个容器还包含一系列的部分如Lodder、 Loggee、 Manager、 Realm和Resources。
更有意思的是Container接口被设计成Tomcat管理员可以通过server.xml文件配置来决定其工作方式的模式。它通过一个pipeline(流水线)和一系列的阀门来实现
org.apache.catalina中四个相关的接口:Pipeline, Valve, ValveContext, 和 Contained。
Pipeline 流水线接口
Value 阀门接口
ValueContext 阀门上下文接口
Contained
一个pipeline包含了改容器要唤醒的所有任务。每一个阀门表示了一个特定的
任务。一个容器的流水线有一个基本的阀门,但是你可以添加任意你想要添加的
阀门。阀门的数目定义为添加的阀门的个数(不包括基本阀门)
如果你已经理解了servlet过滤器,那么流水线和它的阀门的工作方式不难想象。
一个流水线就像一个过滤链,每一个阀门像一个过滤器。跟过滤器一样,一个阀
门可以操作传递给它的request和response 方法。让一个阀门完成了处理,则
进一步处理流水线中的下一个阀门,基本阀门总是在最后才被调用。
一个容器可以有一个流水线。当容器的invoke方法被调用的时候,容器将会处
理流水线中的阀门,并一个接一个的处理,直到所有的阀门都被处理完毕
流水线必须保证说要添加给它的阀门必须被调用一次,流水线通过创建一
个ValveContext接口的实例来实现它。ValveContext是流水线的的内部类,这
样ValveContext就可以访问流水线中所有的成员。ValveContext中最重要的方
法是invokeNext方法:
3、Wrapper(包装器)
org.apache.catalina.Wrapper接口表示了一个包装器。一个包装器是表示一个
独立servlet定义的容器。包装器继承了Container接口,并且添加了几个方法。
包装器的实现类负责管理其下层servlet的生命中期,包括servlet的
init,service,和destroy方法。由于包装器是最底层的容器,所以不可以将子
容器添加给它。如果addChild方法被调用的时候会产生
IllegalArgumantException异常。
包装器接口中重要方法有allocate和load方法。allocate方法负责定位该包
装器表示的servlet的实例。Allocate方法必须考虑一个servlet是否实现了
avax.servlet.SingleThreadModel接口,该部分内容将会在 11 章中进行讨论。
Load方法负责load和初始化servlet的实例。
Mapper 接口
如何使用一个包含两个包装器的上下文来包装两个
servlet类。当有多于一个得包装器的时候,需要一个 map 来处理这些子容器,
对于特殊的请求可以使用特殊的子容器来处理
####################
容器的invoke()方法调用流水线接口pipeline的invoke方法
流水线通过创建一 个ValveContext 接口的实例来实现它。ValveContext 是流水线的的内部类,这
样ValveContext 就可以访问流水线中所有的成员。ValveContext 中最重要的方
法是 invokeNext方法:
public void invokeNext(Request request, Response response)
throws IOException, ServletException
流水线、阀门的设计很是精巧
1、HttpConnector connector = new HttpConnector();
Wrapper wrapper = new SimpleWrapper();
new连接器,
new包装器时,
public SimpleWrapper() {
pipeline.setBasic(new SimpleWrapperValve());
}
2、SimplePipeline pipeline = new SimplePipeline(this);
流水线Pipeline是包装器的属性类,new流水线时把包装器自己this当做一个容器传递进去
3、pipeline.setBasic(new SimpleWrapperValve());
把基本阀门SimpleWrapperValve setBasic()进去
public void setBasic(Valve valve) {
this.basic = valve;
((Contained) valve).setContainer(container);
}
此处的value其实是SimpleWrapperValve ,container是SimpleWrapper
4、set阀门
((Pipeline) wrapper).addValve(valve1);
((Pipeline) wrapper).addValve(valve2);
connector.setContainer(wrapper); 把包装器当做容器set给连接器
connector.initialize(); 连接器
connector.start();
处理器process(Socket socket)方法中调用容器的invoke方法,这一部分就是默认连接器的处理,请同上面的描述
connector.getContainer().invoke(request, response);
5、也就是调用SimpleWrapper这个包装器的invoke方法
public void invoke(Request request, Response response)
throws IOException, ServletException {
pipeline.invoke(request, response);
}
里面调用了SimplePipeline的invoke(request, response);方法
6、SimplePipeline的invoke(request, response)内
public void invoke(Request request, Response response)
throws IOException, ServletException {
// Invoke the first Valve in this pipeline for this request
(new SimplePipelineValveContext()).invokeNext(request, response);
}
SimplePipelineValveContext 是SimplePipeline的内部类
SimplePipelineValveContext 实现ValveContext接口(阀门上下文接口)
6、调用SimplePipelineValveContext的invokeNext(request, response)
public void invokeNext(Request request, Response response)
throws IOException, ServletException {
int subscript = stage;
stage = stage + 1;
// Invoke the requested Valve for the current request thread
if (subscript < valves.length) {
valves[subscript].invoke(request, response, this);
}
else if ((subscript == valves.length) && (basic != null)) {
basic.invoke(request, response, this);
}
else {
throw new ServletException("No valve");
}
}
} // end of inner class
if else 分别调用 3步设置的基本阀门 4步设置的日志、ip阀门
调用阀门的invoke(request, response, this);时把自己SimplePipelineValveContext传进去
再基本阀门中的调用SimplePipelineValveContext的invokeNext()方法形成类似递归的一个流水线调用
或者说是栈
###
可以使用 setBasic方法来分配一个基本阀门给流水线,getBasic方法会
得到基本阀门。最后被唤醒的基本阀门,负责处理request和回复response。
###
context 接口
一个 context在容器中表示一个web 应用。一个 context通常含有一个或多个包
装器作为其子容器。
重要的方法包括addWrapper, createWrapper 等方法
上下文 容器
--------------------------------------------
6、生命周期
一个实现了Lifecycle接口的组件同是会触发一个或多个下列事件:
BEFORE_START_EVENT, START_EVENT, AFTER_START_EVENT, BEFORE_STOP_EVENT,
STOP_EVENT, and AFTER_STOP_EVENT。当组件被启动的时候前三个事件会被触发,
而组件停止的时候会触发后边三个事件。另外,如果一个组件可以触发事件,那
么必须存在相应的监听器来对触发的事件作出回应。监听器使用
org.apache.catalina.LifecycleListener来表示
Lifecycle 中最重要的方法是start和 stop方法。一个组件提供了这些方法的
实现,所以它的父组件可以通过这些方法来启动和停止他们。另外3个方法
addLifecycleListener, findLifecycleListeners, 和
removeLifecycleListener 事跟监听器相关的类。组件的监听器对组件可能触发
的时间 “感兴趣”,当一个事件被触发的时候,相应监听器会被通知。一个
Lifecycle 实例可以触发使用静态最终字符串定义的六个事件。
LifeCycleEvent类 表示一个生命周期事件
LifeCycleListener接口 表示一个生命周期监听器
该接口中,只有一个方法 lifecycleEvent,该方法在事件触发的时候唤醒对
其 “感兴趣”的监听器
LifecycleSupport 类
connector.initialize();
((Lifecycle) connector).start();
((Lifecycle) context).start();
第5章时 只需要连接器start();
现在需要容器也start()
1、new SimpleContextLifecycleListener()
LifecycleListener listener = new SimpleContextLifecycleListener();
((Lifecycle) context).addLifecycleListener(listener);
2、容器的addLifecycleListener(listener);
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
3、容器实现了Lifecycle 生命周期接口
((Lifecycle) context).start();#显示调用
----------------------------------------
日志系统
FileLogger implements Lifecycle 实现了 生命周期接口
------------------------------
类加载器
一个 servlet容器需要一个定制的容器,而不是简单的使用系统的加
载器。如果像前面章节中那样使用系统的加载器来加载 servlet和其他需要的类,
这样 servlet就可以进入Java虚拟机CLASSPATH 环境下面的任何类和类库,这
会带来安全隐患。Servlet 只允许访问WEB-INF/目录及其子目录下面的类以及部
署在WEB-INF/lib 目录下的类库。
Tomcat 需要一个自己的加载器的另一个原因是它需要支持在WEB-INF/classes
或者是WEB-INF/lib 目录被改变的时候会重新加载。Tomcat 的加载器实现中使
用一个单独的线程来检查 servlet和支持类文件的时间戳。要支持类的自动加载
功能,一个加载器类必须实现org.apache.catalina.loader.Reloader接口
1、其中bootstrap类加载器用于引导 JVM,一旦调用java.exe程序,bootstrap
类加载器就开始工作。因此,它必须使用本地代码实现,然后加载 JVM 需要的类
到函数中。另外,它还负责加载所有的Java 核心类,例如 java.lang和 java.io
包。另外bootstrap类加载器还会查找核心类库如 rt.jar、i18n.jar等,这些
类库根据 JVM和操作系统来查找。
extension类加载器负责加载标准扩展目录下面的类。这样就可以使得编写程序
变得简单,只需把JAR 文件拷贝到扩展目录下面即可,类加载器会自动的在下面
查找。不同的供应商提供的扩展类库是不同的,Sun 公司的JVM 的标准扩展目录
是/jdk/jre/lib/ext。
system加载器是默认的加载器,它在环境变量CLASSPATH 目录下面查找相应的
类。
这样,JVM 使用哪个类加载器?答案在于委派模型(delegation model)
委派模型对于安全性是非常重要的
---------------------------------------------------------
13 Host和Engine
engine 表示了整个catalina 的servlet 引擎。engine 是处于最顶层的container。被添加到engine 的子
container 通常是org.apache.catalina.Host 或org.apache.catalina.Context。tomcat 默认是使用engine 的
-----------------------------------------------------------
14 Server与Service
在前面的章节中,已经说明了connector 和container 是如何工作的.在8080 端口上,只能有一个connector
服务于http 请求
org.apache.catalina.Server 接口表示了整个catalina 的servlet 引擎,囊括了所有的组件。server 使用一种
优雅的方法来启动/停止整个系统,不需要对connector 和container 分别启动/关闭
相关推荐
本篇将聚焦于"Tomcat源码阅读(一)——环境搭建",探讨如何搭建一个适合源码学习的开发环境。 首先,我们需要了解Tomcat是什么。Tomcat是一款开源的Java Servlet容器,由Apache软件基金会维护,实现了Java EE中的...
【标签】: "Tomcat源码" 标签明确指出了主题的核心——Tomcat的源代码。源码阅读对于开发者来说是提升技能的关键步骤,可以理解Tomcat内部的工作机制,如请求处理流程、线程管理、连接器和容器的交互等,这对于性能...
1. 下载Tomcat源码:可以从Apache官网获取Tomcat 6的源码包,例如这里我们使用的是apache-tomcat-6.0.44-study。 2. 导入源码项目:在Idea中选择“Open”打开源码目录,Idea会自动识别为Maven项目。 3. 配置Maven...
通过阅读和分析Tomcat源码,我们可以学习到以下知识点: 1. **Servlet生命周期**:Tomcat如何加载、初始化、服务、销毁Servlet,以及ServletConfig和ServletContext的角色。 2. **线程池管理**:Tomcat如何使用...
源码解析部分则是对Tomcat源码的深度剖析,涵盖了关键类和方法的作用、设计模式的运用以及性能优化技巧。这有助于开发者理解Tomcat内部的工作流程,例如,如何处理HTTP请求的生命周期,以及线程池是如何调度和管理的...
参考http://www.cnblogs.com/huangfox/archive/2011/10/20/2218970.html下面阅读tomcat源码所需的jar,版本可能不同,至少未编译之前没有报错了。
本篇将详细介绍如何使用Ant编译Tomcat源码,以及如何在MyEclipse环境中导入并运行Tomcat源码。 首先,Ant是Apache软件基金会开发的Java项目自动化构建工具,它能够执行编译、测试、打包等任务。在Apache Tomcat的...
【标签】"源码"和"tomcat8"提示我们,我们将关注的是Tomcat 8版本的源代码。Tomcat 8是一个重要的版本,引入了Java EE 7的支持,包括WebSocket API等新特性。源码分析可以帮助开发者理解这些特性的实现细节,以及...
【标签】"tomcat源码分析"表明整个资料集专注于Tomcat的源代码级探索,适合于开发者或运维人员深入了解服务器的底层实现。 【文件名称列表】中的每个文档都对应一个特定主题: 1. "Tomcat处理HTTP请求源码分析.doc...
Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache ...
这个源码包,"apache-tomcat-6.0.43-src",是Tomcat 6的官方源代码,非常适合开发者进行深入学习和自定义修改。以下是基于这个源码包的一些关键知识点: 1. **Servlet容器**:Tomcat作为Servlet容器,其主要任务是...
通过阅读源代码,你不仅可以了解Tomcat的工作流程,还可以学习到很多Java多线程、网络编程、容器设计模式和安全管理等方面的知识,这对于提升你的Java Web开发技能大有裨益。同时,这也有助于你更好地调试和优化在...
《深入剖析Tomcat7源码》 Tomcat7是一款广泛使用的开源Java Servlet容器,它实现了Java EE中的...通过学习源码,我们可以了解到如何编写高效、健壮的服务器端代码,这对于任何Java开发者来说都是一笔宝贵的财富。
这份源代码资料,提供了Tomcat 6.0.43版本的源码,让我们有机会一窥其内部的运行机制。 首先,我们需要了解Tomcat的基础架构。Tomcat是Apache软件基金会下的一个项目,它是一个开源的、免费的Web应用服务器,主要...
在IT行业中,深入理解Web服务器的内部工作原理是至关重要的,特别是对于Java开发者而言,Tomcat作为最常用的Servlet容器,其源代码的阅读能够帮助我们更好地优化应用性能、解决复杂问题以及理解HTTP协议的实现。...
7. **理解文档**:阅读提供的导入说明,理解如何配置和使用Tomcat源码,以及可能遇到的问题和解决方案。 8. **编译和运行**:在MyEclipse中编译源码,并可以尝试运行Tomcat服务器,验证导入是否成功。 通过这个过程...
《深入剖析Tomcat源代码:探索底层实现原理》 Tomcat作为开源的Java Servlet容器,是许多Web开发者和系统管理员的首选。它以其轻量级、高效和稳定性著称,而深入理解其源代码,有助于我们更好地优化应用性能,解决...
通过阅读"TOMCAT源码分析.doc"和解压后的"apache-tomcat-6.0.0-src.zip",你可以深入了解上述知识点,并学习如何根据源码进行调试、优化或扩展Tomcat。这份资料对于Java Web开发者来说是一份宝贵的参考资料,有助于...