tomcat源码解读(一)

tomcat源码解读(一)

什么是 tomcat /h2>

简而言之:tomcat是一个接受 http 请求并解析 http 请求并反馈客户端的一个应用程序.

tomcat 可以说是 sun Servlet 的一个官方参考实现, 因为 tomcat 刚开始就是 sun 开发的,后来捐献给了 apache 基金会.

在我们理解 tomcat 之前, 我们得了解一下tomcat 所实现的 Servlet 是什么/p>

那要从互联 大潮兴起开始讲起, 我们知道, 页不止有静态的还有动态的, 而在刚开始的时候, 常见的实现动态 页的技术就是 CGI, 但是作为 Java 的发明人, SUN|肯定要搞一个超级大风头, 让整个世界一下子认识了 Java, 不过很快悲催的发现 Applet 其实用途不大, 眼看着互联 开始流行, 一定要搭上千载难逢的快车啊.

于是, Servlet 就诞生了, Servlet 其实就是 SUN 为了让 Java 能实现动态的可交互的 页, 从而进入 web 编程的领域而定义的一套标准.

这套标准是这么说的: 你想用 Java 开发动态 页, 可以定义一个自己的” Servlet”, 但一定要实现我的 HTTPServlet 接口, 然后重载 doGet(), doPost()方法. 用户从流浪器 GET 的时候, 调用 doGet 方法, 从流浪器向服务器发送表单数据的时候, 调用 doPost 方法, 如果你想访问用户从浏览器传递过来的参数, 用 HttpServletRequest 对象就好了, 里面有 getParameter, getQueryString 方法, 如果你处理完了, 想向浏览器返回数据, 用 HttpServletResponse 对象调用 getPrintWriter 方法就可以输出数据了.

如果你想实现一个购物车, 需要 session, 很简单, 从 HttpServletRequest 调用 getSession 方法就可以了.

Servlet 是如何工作的
servlet 是一个复杂的系统, 但是他有三个基本任务, 对每个请求, servlet 容器会为其完成以下3个操作:

??(1) 创建一个 Request 对象, 用可能会在调用的 Servlet 中使用到的信息填充该 Request 对象, 如参数, 头, cookie, 查询字符串, URI 等, Request 对象是 javax.servlet.ServletRequest 接口或 javax.servlet.ServletRequest 接口的一个实例.
??(2) 创建一个调用 Servlet 的 Response 对象, 用来向 Web 客户端发送响应. response 对象是 javax.servlet.http.ServletResponse 接口或 javax.servlet.ServletResponse 接口的一个实例;
??(3) 调用 Servlet 的 service 方法, 将 request 对象和 response 对象作为参数传入, Servlet 从 request 对象中读取信息, 并通过 response 对象发送响应信息.

你写了一个” Servlet”, 接下来要运行, 你就发现没法通过 java 直接运行了, 你需要一个能够运行 Servlet 的容器, 这个容器 Sun 最早实现了一个, 叫 Java Web Server, 1999年捐给了 Apache Software foundation, 就改名叫 Tomcat. 这就是 Tomcat 的由来.

所以, Tomcat 就是一个 Servlet 容器, 能接收用户从浏览器发来的请求, 然后转发给 Servlet 处理, 把处理完的响应数据发回浏览器.

但是 Servlet 输出 Html, 还是采用了老的 CGI 方式 , 是一句一句输出, 所以,编写和修改 html 非常不方便, 于是, Java Server Pages(JSP) 就来救急了, JSP 并没有增加任何本质上不能用 Servlet 实现的功能, 实际上 JSP 在运行之前, 需要先编译成 Servlet, 然后才执行的.

但是, 在 JSP 中编写静态 HTML 更加方便, 不必再用 println 语句来输出每一行HTML 代码, 更重要的是, 借助内容和外观的分离,页面制作中不同性质的任务可以方便的分开: 比如, 有页面设计者进行 HTML 设计, 同时流出供 Java 程序插入动态内容的空间.

Tomcat 能运行 Servlet, 当然能运行 JSP 了.

既然是 Web 服务器, tomcat 除了能运行 Servlet 和 JSP 之外, 也能像 Apache/nginx 一样, 支持静态 html, 图片, 文档的访问, 只是性能差一点,在实际的应用中, 一般是 Apache/nginx 作为负载均衡服务器和静态资源服务器放在最前端, 后面是 tomcat 组成的集群.

如果用户请求的是静态资源, nginx 直接搞定, 如果是动态资源(如xxx.jsp), nginx 就会按照一定的算法转发的某个 tomcat 上, 达到负载均衡的目的.

Tomcat 是如何设计的有哪些所谓的组件/h2>

首先可以通过下面图来进行简要的说明

??需求被传递到了容器里面, 在合适的时候, 会传递给下一个容器处理。而容器里面又盛装着各种各样的组件, 我们可以理解为提供各种各样的增值服务。比如:

换个角度再来看看 Tomcat 的总体架构:

  • 面向组件架构
  • 基于JMX
  • 事件侦听

面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成,如Server、Service、Connector等,并基于JMX管理这些组件,另外实现以上接口的组件也实现了代表生存期的接口Lifecycle,使其组件履行固定的生存期,在其整个生存期的过程中通过事件侦听LifecycleEvent实现扩展。Tomcat的核心类图如下所示:

tomcat源码解读(一)
上面我们已经对每个类的功能进行了一些描述.包括 Catalina 类和 Server 类的作用, Service 类是如何关联 Connector 和 Container 的. 还有各个容器是上面关系. 包括容器中数据是如何从从管道( pipeline) 中传递, 还有一些组件, 比如类载入器, 管理器, 安全主体( realm);

基于JMX Tomcat会为每个组件进行注册过程,通过Registry管理起来,而Registry是基于JMX来实现的,因此在看组件的init和start过程实际上就是初始化MBean和触发MBean的start方法,会大量看到形如: Registry.getRegistry(null, null).invoke(mbeans, “init”, false); Registry.getRegistry(null, null).invoke(mbeans, “start”, false); 这样的代码,这实际上就是通过JMX管理各种组件的行为和生命期。

那么, 什么是 JMX 呢/p>

事件侦听(观察者模式/事件驱动) 各个组件在其生命期中会有各种各样行为,而这些行为都有触发相应的事件,Tomcat就是通过侦听这些时间达到对这些行为进行扩展的目的。在看组件的init和start过程中会看到大量如: lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);这样的代码,这就是对某一类型事件的触发,如果你想在其中加入自己的行为,就只用注册相应类型的事件即可。

文章知识点与官方知识档案匹配,可进一步学习相关知识 络技能树首页概览22557 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年9月14日
下一篇 2021年9月14日

相关推荐