質問:TomcatのWebサービスを作成するためにどのようにする機能を有していますか?
HTTPを使用してサーバーを監視するには、プロトコルが書き込み、リスナーとしてパッケージされたJavaソケットを使用したいと思うかもしれません。
クラスMyTomcat { ServerSocketをサーバー=新しいServerSocketを(8080); //クライアント接続要求の待機ソケットのソケット= server.accept(); }
1.2.3 Servlet容器
質問:Tomcatのサーブレットコンテナを作るためにどのようにする機能を有していますか?あの白いサーブレットのいずれかをインストールすることができます。
サーブレットは何ですか?
パブリック インターフェースサーブレット{ ボイドのinit(のServletConfigの設定)がServletExceptionががスロー。 ServletConfigのgetServletConfig()。 空サービス(のServletRequest reqは、ServletResponseをRES)はServletExceptionが、IOExceptionがスローされます。 ストリングgetServletInfo()。 無効)(破壊します。 }
クラスがloginservletはHttpServletを拡張{ doGet(リクエスト、レスポンス){}のdoPost(リクエスト、レスポンス){} }
<servlet> <servlet-name>のがloginservlet </サーブレット名> <servlet- クラス > com.gupao.web.servlet.LoginServlet </ servlet- クラス > </サーブレット> <のservlet-mapping> <servlet-name>のがloginservlet </サーブレット名> <url-pattern> /ログイン</のurl-pattern> </のservlet-mapping>
1.2.4最適化MyTomcat
クラスMyTomcat { リスト一覧 = 新しいArrayListを(); ServerSocketをサーバー = 新しい ServerSocketを(8080 ); ソケットソケット = server.accept(); // 要求と応答は、サーブレットは、サービスコードでカプセル化される // 単に缶のTomcatサーブレット1つのサービスコードを追加 List.add(サーブレット)。 }
マップを描く1.2.5
情報は、1.2.6を得ました
(1)Tomcatサーブレット仕様では、サポートを必要と
Tomcatの/ libに/サーブレット-api.jarを
(2)Webコンテナ
新しいServerSocketを(8080)のためのTomcatのソースコードを期待している、と確認しながらもあります
(3)servlet容器
確認しながら希望Tomcatのソースコードはまた、(サーブレット)コードをlist.addれます
02製品とソースコード
2.1バージョンを選択しました
Tomcatのバージョン:Tomcat8.0.11の
バージョンをダウンロードします。https://archive.apache.org/dist/tomcat
2.2カタログファイルの意味
(1)ビン:主に店舗のコマンドを使用し、次のウィンドウでの.bat、Linuxである.SH
(2)CONF:主にTomcatの設定ファイルを保存するために使用
(3)LIB:ジャーパッケージ依存のTomcatの一部を保存します
(4)ログ:Tomcatのストアログファイル操作中に発生しました
(5)一時:一時ファイルが格納されているランタイム
(6)Webアプリケーション:ストレージアプリケーション
(7)仕事:そのようにコンパイルJSPファイルなどの実行時にTomcatコンパイルされたファイルを保存
2.3インポートおよびデバッグソースコード
(1)上記リンクのTomcatに応じて、ダウンロードしたソースコードに対応します
(2)创建pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.tomcat</groupId> <artifactId>Tomcat8.0</artifactId> <name>Tomcat8.0</name> <version>8.0</version> <build> <finalName>Tomcat8.0</finalName> <sourceDirectory>java</sourceDirectory> <testSourceDirectory>test</testSourceDirectory> <resources> <resource> <directory>java</directory> </resource> </resources> <testResources> <testResource> <directory>test</directory> </testResource> </testResources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3</version> <configuration> <encoding>UTF-8</encoding> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>ant</groupId> <artifactId>ant</artifactId> <version>1.7.0</version> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>javax.xml</groupId> <artifactId>jaxrpc</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>org.eclipse.jdt.core.compiler</groupId> <artifactId>ecj</artifactId> <version>4.5.1</version> </dependency> </dependencies> </project>
(3)将源码导入到idea中
(4)创建Application,名称为gp-tomcat,并且填写相关信息
name:gp-tomcat Main class:org.apache.catalina.startup.Bootstrap
VM options:-Dcatalina.home="apache-tomcat-8.0.11
(5)在当前源码目录创建apache-tomcat-8.0.11文件夹,并且将一些文件拷贝到该目录下
比如bin conf lib logs temp webapps work
(6)启动,发现报错,找不到CookieFilter,直接删除
(7)打开浏览器访问:localhost:8080
03 验证上述猜想
(1)web容器 (2)servlet容器
3.1 Web容器
Connector.initInternal()->
protocolHandler.init()->
AbstractProtocol.init()->
endpoint.init()->
bind()->
Apr,JIo,NIO,NIO2->
JIo即Socket实现方式
3.2 Servlet容器
web项目--->Context标签--->Context.class--->StandardContext--->loadOnStartup()
证明Wrapper就是Servlet :
加载:ContextConfifig.webConfifig()—>getContextWebXmlSource()—>Constants.ApplicationWebXml
解析:ContextConfifig.webConfifig()—>confifigureContext(webXml)—>context.createWrapper()
3.3. 进一步思考
既然Context表示标签能够表示Web项目,那按照server.xml文件来看的话,不就能够把tomcat架构图画出来
了吗?或者按照之前的简略版推导出来。
Context,Host,Engine,Service等
为什么知道找Connector?
再次回到conf/web.xml文件,发现有一个Connector标签,而且还可以配置port端口,我们能够联想到监听端口,
按照配置文件到源码类的经验,源码中一定会有这样一个Connector类用于端口的监听。
conclusion :架构图<--->server.xml<--->源码 三者有一一对应的关系
04 Tomcat架构设计
4.1 各个组件含义
官网 :https://tomcat.apache.org/tomcat-8.0-doc/architecture/overview.html
4.2 两个核心组件
Connector:主要负责处理Socket连接,以及Request与Response的转化
Container:包括Engine、Host、Context和Wrapper,主要负责内部的处理以及Servlet的管理
4.2.1 Connector
设计思想 :高内聚、低耦合
EndPoint:提供字节流给Processor
Processor:提供Tomcat Request对象给Adapter
Adapter:提供ServletRequest给容器
4.2.1.1 EndPoint
监听通信端口,是对传输层的抽象,用来实现 TCP/IP 协议的。
对应的抽象类为AbstractEndPoint,有很多实现类,比如NioEndPoint,JIoEndPoint等。在其中有两个组件,一个
是Acceptor,另外一个是SocketProcessor。
Acceptor用于监听Socket连接请求,SocketProcessor用于处理接收到的Socket请求。
4.2.1.2 Processor
Processor是用于实现HTTP协议的,也就是说Processor是针对应用层协议的抽象。
Processor接受来自EndPoint的Socket,然后解析成Tomcat Request和Tomcat Response对象,最后通过Adapter
提交给容器。
对应的抽象类为AbstractProcessor,有很多实现类,比如AjpProcessor、Http11Processor等。
4.2.1.3 Adpater
ProtocolHandler接口负责解析请求并生成 Tomcat Request 类。
需要把这个 Request 对象转换成 ServletRequest。
Tomcat 引入CoyoteAdapter,这是适配器模式的经典运用,连接器调用 CoyoteAdapter 的 sevice 方法,传入的是
Tomcat Request 对象,CoyoteAdapter 负责将 Tomcat Request 转成 ServletRequest,再调用容器的 service 方
法。
4.2.1.4 优化图解
Endpoint接收Socket连接,生成一个SocketProcessor任务提交到线程池去处理
SocketProcessor的run方法会调用Processor组件去解析应用层协议,
Processor通过解析生成Request对象后,会调 用Adapter的service方法。
4.2.2 Container
通过Connector之后,我们已经能够获得对应的Servlet
4.3 Request Process Flow
官网 :https://tomcat.apache.org/tomcat-8.0-doc/architecture/requestProcess/request-process.png
05 思维扩展
5.1 自定义类加载器
WebAppClassLoader,打破了双亲委派模型:先自己尝试去加载这个类,找不到再委托给父类加载器。
通过复写findClass和loadClass实现。
5.2 Session管理
Context中的Manager对象,查看Manager中的方法,可以发现有跟Session相关的。
Session 的核心原理是通过 Filter 拦截 Servlet 请求,将标准的 ServletRequest 包装一下,换成 Spring 的
Request 对象,这样当我们调用 Request 对象的 getSession 方法时,Spring 在背后为我们创建和管理
Session。
06 Tomcat源码解读
6.1 BootStrap
BootStrap是Tomcat的入口类
bootstrap.init() 和 创建Catalina
6.2 Catalina
解析server.xml文件
创建Server组件,并且调用其init和start方法
6.3 Lifecycle
用于管理各个组件的生命周期
init、start、stop、destroy
LifecycleBase实现了Lifecycle,利用的是模板设计模式
6.4 Server
管理Service组件,并且调用其init和start方法
6.5 Service
管理连接器和Engine