您的位置:首页 > 运维架构 > Tomcat

[源码学习]Tomcat6 源码学习-1

2010-04-07 10:00 399 查看
Tomcat6 源码学习

2010-3-29

【tomcat启动类Bootstrap】

t1.tomcat的人口函数,启动类

org.apache.catalina.startup. Bootstrap.java   Main函数

t2.Bootstrap类

初始化 ClassLoader, 然后利用 Java Reflection 调用 Catalina 类来启动 tomcat server

【tomcat扩展-日志】

a1.private static Log log = LogFactory.getLog(Bootstrap.class);

日志可以定义为private 和static

a2.只在本类中使用的方法,使用private,降低访问权限,需要的时候,再考虑重构或者提高访问权限public

a.日志打印前加if(log.isInfoEnabled())

如果代码中含有logger.debug(“string”);此类语句,尽管在log4j.xml配置文件中对该类logger的level为
ERROR,但是仍然会产生较大的内存开销,通常是所要输出的string的几十倍甚至上百倍大小,对内存开销非常大。优化方法为:使用logger进行
判断。

2010-3-30

【tomcat扩展-classloader】

a3.如果两个类属于同一个包下,但是由不同的classloader加载,那么他们也不能互访default类型方法,属性

a4.classloader:与C或C++编写的程序不同,Java程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件基本上
对应于一个类。此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader是JVM中将类装入内存的那部分

a5.定制的ClassLoader应用:

1.在执行非置信代码之前,自动验证数字签名

2.使用用户提供的密码透明地解密代码

3.动态地创建符合用户特定需要的定制化构建类

4.任何您认为可以生成Java字节码的内容都可以集成到应用程序中

a6.findClass方法是创建定制的ClassLoader时唯一需要覆盖的方法。

ClassLoader loadClass方法

Class c = findLoadedClass(name);

if (c == null) {

    try {

if (parent != null) {

    c = parent.loadClass(name, false);

} else {

    c = findBootstrapClass0(name);

}

    } catch (ClassNotFoundException e) {

        // If still not found, then invoke findClass in order

        // to find the class.

        c = findClass(name);

    }

}

a7.ClassLoader(CCL)的任务是确保代码被编译和更新。

下面描述了它的工作方式:1、当请求一个类时,先查看它是否在磁盘的当前目录或相应的子目录。

2、如果该类不存在,但源码中有,那么调用Java编译器来生成类文件。

3、如果该类已存在,检查它是否比源码旧。如果是,调用Java编译器来重新生成类文件。

4、如果编译失败,或者由于其它原因不能从现有的源码中生成类文件,返回ClassNotFoundException。

5、如果仍然没有该类,也许它在其它库中,所以调用findSystemClass来寻找该类。

6、如果还是没有,则返回ClassNotFoundException。

7、否则,返回该类。

8、调用findLoadedClass来查看是否存在已装入的类。

9、如果没有,那么采用那种特殊的神奇方式来获取原始字节。

10、如果已有原始字节,调用defineClass将它们转换成Class对象。

11、如果没有原始字节,然后调用findSystemClass查看是否从本地文件系统获取类。

12、如果resolve参数是true,那么调用resolveClass解析Class对象。

13、如果还没有类,返回ClassNotFoundException。

14、否则,将类返回给调用程序。

【tomcat启动类classloader】

t3.tomcat自定义了三个类,catalinaLoader commonLoader,sharedLoader

Common - 载入$CATALINA_HOME/common/...它们对TOMCAT和所有的WEB APP都可见

Catalina - 载入$CATALINA_HOME/server/..它们仅对TOMCAT可见,对所有的WEB APP都不可见

Shared-载入$CATALINA_HOME/shared/它们仅对所有WEB APP可见,对TOMCAT不可见(也不必见)

t4.Bootstrap通过反射初始化Catalina类,

反射调用Catalina方法setParentClassLoader,传递SharedClassloader

反射call Catalina方法load 利用server.xml中的配置初始化Service,Server,Engine,Host

反射call Catalina方法start Start the new server  该server是通过 
解析xml文件生成的org.apache.catalina.core.StandardServer类

【tomcat-xml解析】

1.Tomcat取了Digester中的interface和几个Rule,并且自己实现了一些 Rule 来解析xml.

2.tomcat解析xml创建以下几个类

Server:

org.apache.catalina.core.StandardServer

Resources:

org.apache.catalina.deploy.NamingResources

Server's Listener:( 监听server事件)

org.apache.catalina.core.AprLifecycleListener

org.apache.catalina.core.JasperListener

org.apache.catalina.mbeans.ServerLifecycleListener

org.apache.catalina.mbeans.GlobalResourcesLifecycleListener

Service:

org.apache.catalina.core.StandardService

Executor:

org.apache.catalina.core.StandardThreadExecutor

Engine:

org.apache.catalina.core.StandardEngine

Connector:

org.apache.catalina.connector.Connector

【tomcat-流程】

3.StandardServer启动StandardService,StandardService启动Connector,

Connector启动Http11Protocol,Http11Protocol启动JIoEndpoint,

JioEndpoint启动server Socket,listern 8080端口,处理http请求

4.Http11Processor

Processes HTTP requests.

由http11ConnectionHandler调用,Http11ConnectionHandler由JioEndpoint中的Work
调用

5.A connector passes the request and reponse objects to the
Container by calling the Container interface's invoke method

public void invoke(Request request, Response response)

        throws IOException, ServletException;

inside the invoke method ,the container loads the servlet class,call
its sevice method ,manage sessions,etc.

6.Connector 方法initialize中

// Initializa adapter

adapter = new CoyoteAdapter(this);

protocolHandler.setAdapter(adapter);

adapter通过protocolHandler(Http11Protocol)传给Http11Processor,

Http11Processor解析,create request和response,通过adapter传送给Container

7.Tomcat使用Pipeline模式在各层容器间传递请求,将请求通过管道依次通过Engine,Host,Context和
Wrapper。另外,每一个容器  

都可以设置一系列的Valve去对请求进行拦 截,就像管道中的阀一样对请求的行为进行一些干涉。

2010-3-31

【tomcat-流程】

1.tomcat的pipeline/valve是标准的责任链模式,每个级别的容器中pipeline所有的valve都完成动作后会将
request/response传到下一个容器的pipeline中的valve,

这样一直传递下去直到Wrapper的BaseValve.

Ps:每个容器的BaseValve会调用下个容器的起始valve

2.StandardEngine

属性Pipeline  pipeline = new StandardPipeline(this);

构造函数里会设置最底层的阀门

pipeline.setBasic(new StandardEngineValve());

如果需要设置新阀门处理需求,只需要调用 pipeline.addValve(Valve valve);

3.CoyoteAdapter中会执行

connector.getContainer().getPipeline().getFirst().invoke(request,
response);

该行代码会一层一层调用添加的阀门,处理下去.

2010-4-1

【tomcat-流程】

1.jk插件负责tomcat和其它http容器进行通信

2.连接器协议AJP/1.3是tomcat用来与其它http容器进行连接的协议

3.把指定Context的classloader付给当前线程。

Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());
这样request就只看见指定的context下面的classes和jar包,而看不见tomcat本身的类。

2010-4-7

【tomcat-socke与worker线程】

/**

* Process an incoming TCP/IP connection on the specified socket. 
Any

* exception that occurs during processing must be logged and
swallowed.

* <b>NOTE</b>:  This method is called from our
Connector's thread.  We

* must assign it to our own thread so that multiple simultaneous

* requests can be handled.

* @param socket TCP socket to process

*/

synchronized void assign(Socket socket) {

// Wait for the Processor to get the previous Socket

while (available) {

try {

              wait();

       } catch (InterruptedException e) {

       }

    }

    // Store the newly available Socket and notify our thread

    this.socket = socket;

    available = true;

    notifyAll();

}

/**

* Await a newly assigned Socket from our Connector, or
<code>null</code

* if we are supposed to shut down.

*/

private synchronized Socket await() {

// Wait for the Connector to provide a new Socket

while (!available) {

try {

wait();

} catch (InterruptedEx
ace9
ception e) {

}

}

    // Notify the Connector that we have received this Socket

    Socket socket = this.socket;

    available = false;

    notifyAll();

return (socket);

}

连接器线程调用worker类的assign类,worker类的执行线程run方法会调用await方法获取socket,通过
available变量的设置和wait/notify方法来协调彼此的操作。当连接器线程未传输socket,worker类线程就执行wait等待,

当worker类执行线程在处理忙的时候,连接器线程wait。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息