思考 :怎样让Tomcat具备Web服务的功能呢?

在服务端用HTTP来监听,协议不好写,不妨用Java封装好的Socket作为监听。
  1. class MyTomcat{
  2. ServerSocket server=new ServerSocket(8080);
  3. // 等待客户端的连接请求 Socket socket=server.accept();
  4. }

  

1.2.3 Servlet容器
思考 :怎样让Tomcat具有Servlet容器的功能呢?说白了就是能够装一个个的Servlet。
Servlet是啥? 
  1. public interface Servlet {
  2. void init(ServletConfig config) throws ServletException;
  3.  
  4. ServletConfig getServletConfig();
  5.  
  6. void service(ServletRequest req, ServletResponse resthrows ServletException, IOException;
  7.  
  8. String getServletInfo();
  9.  
  10. void destroy();
  11. }
  1. class LoginServlet extends HttpServlet {
  2. doGet(request,response){} doPost(request,response){}
  3. }
  1. <servlet>
  2. <servlet-name>LoginServlet</servlet-name>
  3. <servlet-class>com.gupao.web.servlet.LoginServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>LoginServlet</servlet-name>
  7. <url-pattern>/login</url-pattern>
  8. </servlet-mapping>
1.2.4 优化MyTomcat 
  1. class MyTomcat{
  2. List list=new ArrayList();
  3. ServerSocket server=new ServerSocket(8080);
  4. Socket socket=server.accept();
  5. // 把请求和响应都封装在业务代码中的servlet
  6. // 只要把业务代码中一个个servlets添加到tomcat中即可
  7. list.add(servlets);
  8. }
1.2.5 画个图

1.2.6 获得的信息
(1)tomcat需要支持servlet规范
tomcat/lib/servlet-api.jar
(2)web容器
希望tomcat源码中也有new ServerSocket(8080)的代码,一会儿验证
(3)servlet容器
希望tomcat源码中也有list.add(servlets)的代码,一会儿验证
 
02 产品和源码
2.1 Version choose

Tomcat版本:Tomcat8.0.11
各个版本下载地址 :https://archive.apache.org/dist/tomcat

2.2 产品目录文件含义
(1)bin:主要用来存放命令,.bat是windows下,.sh是Linux下
(2)conf:主要用来存放tomcat的一些配置文件
(3)lib:存放tomcat依赖的一些jar包
(4)logs:存放tomcat在运行时产生的日志文件
(5)temp:存放运行时产生的临时文件
(6)webapps:存放应用程序
(7)work:存放tomcat运行时编译后的文件,比如JSP编译后的文件
2.3 源码导入与调试
(1)根据上面的链接下载对应的tomcat源码
(2)创建pom.xml文件 
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>org.apache.tomcat</groupId>
  6. <artifactId>Tomcat8.0</artifactId>
  7. <name>Tomcat8.0</name>
  8. <version>8.0</version>
  9. <build>
  10. <finalName>Tomcat8.0</finalName>
  11. <sourceDirectory>java</sourceDirectory>
  12. <testSourceDirectory>test</testSourceDirectory>
  13. <resources>
  14. <resource>
  15. <directory>java</directory>
  16. </resource>
  17. </resources>
  18. <testResources>
  19. <testResource>
  20. <directory>test</directory>
  21. </testResource>
  22. </testResources>
  23. <plugins>
  24. <plugin>
  25. <groupId>org.apache.maven.plugins</groupId>
  26. <artifactId>maven-compiler-plugin</artifactId>
  27. <version>2.3</version>
  28. <configuration>
  29. <encoding>UTF-8</encoding>
  30. <source>1.8</source>
  31. <target>1.8</target>
  32. </configuration>
  33. </plugin>
  34. </plugins>
  35. </build>
  36. <dependencies>
  37. <dependency>
  38. <groupId>junit</groupId>
  39. <artifactId>junit</artifactId>
  40. <version>4.12</version>
  41. <scope>test</scope>
  42. </dependency>
  43. <dependency>
  44. <groupId>org.easymock</groupId>
  45. <artifactId>easymock</artifactId>
  46. <version>3.4</version>
  47. </dependency>
  48. <dependency>
  49. <groupId>ant</groupId>
  50. <artifactId>ant</artifactId>
  51. <version>1.7.0</version>
  52. </dependency>
  53. <dependency>
  54. <groupId>wsdl4j</groupId>
  55. <artifactId>wsdl4j</artifactId>
  56. <version>1.6.2</version>
  57. </dependency>
  58. <dependency>
  59. <groupId>javax.xml</groupId>
  60. <artifactId>jaxrpc</artifactId>
  61. <version>1.1</version>
  62. </dependency>
  63. <dependency>
  64. <groupId>org.eclipse.jdt.core.compiler</groupId>
  65. <artifactId>ecj</artifactId>
  66. <version>4.5.1</version>
  67. </dependency>
  68. </dependencies>
  69. </project>
(3)将源码导入到idea中
(4)创建Application,名称为gp-tomcat,并且填写相关信息
  1. 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. 1web容器 2servlet容器
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 优化图解 
  1. Endpoint接收Socket连接,生成一个SocketProcessor任务提交到线程池去处理
  2. SocketProcessorrun方法会调用Processor组件去解析应用层协议,
    Processor通过解析生成Request对象后,会调 Adapterservice方法。

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 

Tomcat基本原理的更多相关文章

  1. Java工程师必备书单

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  2. 【转】Java工程师必备书单

    江湖路险,你我同行. Java开发工程师一般负责后端开发,当然也有专门做Java Web的工程师,但是随着前后端的分离,越来越多的Java工程师需要往大后端方向发展. 今天我们就来介绍一下Java后端 ...

  3. java后端书单

    Java开发工程师一般负责后端开发,当然也有专门做Java Web的工程师,但是随着前后端的分离,越来越多的Java工程师需要往大后端方向发展. 今天我们就来介绍一下Java后端开发者的书单. 首先要 ...

  4. Java后端工程师必备书单(从Java基础到分布式)

    Java开发工程师一般负责后端开发,当然也有专门做Java Web的工程师,但是随着前后端的分离,越来越多的Java工程师需要往大后端方向发展. 今天我们就来介绍一下Java后端开发者的书单. 首先要 ...

  5. IDE集成管理Tomcat的基本原理

    知道IDE是怎样控制Tomcat的,对更清晰地理解Java Web的执行过程有帮助.在此以IntelliJ IDEA为例,简要描述一下IDE集成管理Tomcat的基本原理. 首先是两个重要的环境变量: ...

  6. 【Web】Tomcat中利用Session识别用户的基本原理

    HTTP无状态的特性与Session.Cookie的存在 HTTP有一个特性:无状态的,就是前后两个HTTP事务它们并不知道对方的信息. 而为了维护会话信息或用户信息,一般可用Cookie或Sessi ...

  7. 全文检索引擎 Solr 部署与基本原理

    全文检索引擎 Solr 部署与基本原理 搜索引擎Solr环境搭建实例 关于 solr , schema.xml 的配置说明 全文检索引擎Solr系列-–全文检索基本原理 一.搜索引擎Solr环境搭建实 ...

  8. linux下tomcat的shutdown命令杀不死进程

    tomcat在windows下可以直接关闭,但是貌似在Linux下有时候shutdown.sh 没有关闭tomcat进程:国庆前最后一天没事,解决你~~~~ 现象: 在Linux下shutdown.s ...

  9. JSP基本原理

    JSP的基本原理: jsp的本质是servlet.jsp通过在标准的HTML页面中嵌入java代码,其静态的部分无需Java程序控制,只有那些需要从数据库读取或需要 动态生成的的页面内容,才使用Jav ...

随机推荐

  1. 渗透测试中期--漏洞复现--MS08_067

    靶机:Win2k3    10.10.10.130 攻击机:BT5      10.10.10.128 一:nmap 查看WinK3是否开放端口3389 开放3389方法:我的电脑->属性-&g ...

  2. Vue案例之todoLIst实现

    使用Vue实现todolist案例,如有不对敬请大佬多多指教 功能: 1.增加功能:在新增版块里面的输入框内输入数据,点击后面的"添加"按钮,将输入的数据添加到列表中,默认是未完成 ...

  3. FLask之视图

    视图 1 FBV def index(): return render_template('index.html') app.add_url_rule('/index', 'index', index ...

  4. [微信小程序]字体文件,字体图标(.ttf,.woff,woff2)等无法显示问题

    一. 背景 项目引用了第三方UI框架Vant-weapp,但是前几天Vant的cdn被运营商封禁,导致van-icon无法使用. 有赞官方在Github上给出了在小程序app.wxss上添加以下代码的 ...

  5. thinkphp如何实现伪静态

    去掉 URL 中的 index.php ThinkPHP 作为 PHP 框架,是单一入口的,那么其原始的 URL 便不是那么友好.但 ThinkPHP 提供了各种机制来定制需要的 URL 格式,配合 ...

  6. HADOOP 之坑

    hadoop 标签: ubuntu hdfs API 概述 通过API访问hdfs文件系统,出现错误:WARN util.Shell:Did not find winutils.exe:{} HADO ...

  7. gcc选项 笔记

    gcc –E hello.c –o hello.i   使用gcc的选项"-E" 让gcc在预处理结束后停止编译过程. gcc –S hello.i –o hello.s   &q ...

  8. DEDECMS:将dedecms系统的data目录迁移到web以外目录

    dedecms系统的data目录是系统缓存和配置文件的目录,一般都有可以读写的权限,只要是能够写入的目录都可能存在安全隐患,很多站长甚至给予这个目录可执行的权限,更是非常危险,所以我们建议将这个dat ...

  9. mysql查询太慢,我们如何进行性能优化?

    老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南.这份指南把大数据的[基础知识][框架分析][源码理解]都用自己的话描述出来,让 ...

  10. I - Swap(交换行列是对角线都为1)

    Given an N*N matrix with each entry equal to 0 or 1. You can swap any two rows or any two columns. C ...