Tomcat源码分析

合集下载

tomcat 默认数据源 dbcp 原理

tomcat 默认数据源 dbcp 原理

tomcat 默认数据源 dbcp 原理Tomcat是一个常用的Java Web服务器,它支持通过配置数据源来连接数据库并进行数据操作。

默认情况下,Tomcat使用的是DBCP(DataBase Connection Pool)作为其连接池技术。

DBCP是Apache软件基金会提供的一个开源的Java数据库连接池实现。

它的原理是在应用启动时,预先创建一定数量的数据库连接,并将这些连接放入连接池中。

当应用需要连接数据库时,直接从连接池中获取一个空闲的连接,用完后再将连接归还给连接池。

这样就可以避免频繁地创建和销毁数据库连接,提高了系统的性能和响应速度。

DBCP的工作原理可以分为以下几个步骤:1. 初始化连接池在Tomcat启动时,会读取配置文件中的数据源信息,根据配置的参数初始化连接池。

这些参数包括数据库的驱动类、连接地址、用户名、密码等。

2. 创建连接连接池在初始化时会创建一定数量的数据库连接,并将这些连接放入连接池中。

连接的数量可以根据配置文件中的参数进行调整。

这些连接在创建时会进行一些必要的初始化操作,如加载数据库驱动、建立与数据库的连接等。

3. 获取连接当应用需要连接数据库时,可以通过调用连接池的方法从连接池中获取一个空闲的连接。

连接池会维护一个连接状态的列表,记录哪些连接是空闲的,哪些连接正在被使用。

4. 使用连接获取到连接后,应用可以使用该连接进行数据库操作,如执行SQL 语句、事务管理等。

在连接使用完毕后,应用需要显式地将连接归还给连接池,以便其他请求可以继续使用该连接。

5. 连接回收连接池会监控连接的使用情况,当连接空闲一定时间后,会自动将连接回收。

回收连接的过程主要包括关闭连接、释放连接占用的资源等。

回收后的连接可以再次被获取和使用。

6. 异常处理在数据库连接的过程中,可能会发生一些异常情况,如连接超时、连接失效等。

连接池会对这些异常进行处理,如重新创建连接、关闭异常连接等。

DBCP作为Tomcat默认的数据源,在使用过程中有一些优点和注意事项:优点:1. 提高性能:连接池可以重复使用已经创建的数据库连接,避免了频繁地创建和销毁连接的开销。

Tomcat单点登录配置及源码分析

Tomcat单点登录配置及源码分析

Tomcat单点登录配置及源码分析我们上网的时候,一定遇到过类似这样的情况,例如使用网易邮箱时进行了登录操作,之后再访问网易的博客系统时,发现自动以之前的ID登录了。

这种实现在计算机中称为SSO(Single Sign On),即我们常说的单点登录。

这种在关联网站间共享认证信息,避免需要在多个系统中重复输入帐户信息的行为,是SSO要解决的。

对于许多应用,可能会独立部署等情况,所以常会采用cas的形式,来实现SSO。

我们今天要了解的,是作为在同一个Tomcat中部署的应用之间,如何实现SSO,避免重复登录。

预备:首先,有几点预备知识需要先了解一下。

1.在Tomcat架构设计中,不同的Container中包含了Peipline。

各个Pipeline中可以添加多种不同形式的Valve。

例如我们之前提到的AccessLogValveTomcat的AccessLogValve介绍2.Tomcat中session的实现,最常用的是Cookie Session, 通过将名为JSESSIONID的cookie写回浏览器,实现session。

我们在前面的文章里也描述过。

深入Tomcat源码分析Session3.关于认证的一些内容,可以参考介绍过的Basic认证。

你可能不了解的Basic认证环境:有了这些准备之后,我们开始进行环境的搭建和实验。

以Tomcat自带的几个应用为例,我们启动Tomcat后,访问这两个应用:docs、examples 我们看到,默认是不需要登录的,都可以直接访问。

此时,在docs应用的web.xml中增加如下配置:Security ConstraintProtected Area/*tomcatBASICSSO Testtomcat此时重启Tomcat,再次请求docs应用,发现需要验证了。

同样,再修改examples应用的web.xml,限制对于其直接访问,在文件中增加如下内容: /*。

Tomcat7源码分析

Tomcat7源码分析

Tomcat源码解析
来看下StandardService的startInternal方法:
Tomcat源码解析
启动Tomcat各级容器会依次先启动 StandardEngine --> StandardHost --> StandardContext(代表一个WebApp应用), 因为我们比较关心我们的Web应用是在哪里 被初始化回调的,所以重点看下 StandardContext的startInternal()方法。
Tomcat源码解析
StandardWrapper容器默认情况下配置 了StandardWrapperValve阀门,主要是找到 当前请求的需要拦截的过滤器Filter及初始化 当前请求的Servlet对象,最终会封装在 FilterChain对象中,责任链方式执行。
Tomcat源码解析
StandardWrapperValve的invoke()方法的核 心代码如下。
目录
1、背景介绍 2、Tomcat源码目录结构 3、Tomcat体系结构 4、Tomcat源码解析
背景介绍
自从JSP发布之后,推出了各式各样的JSP 引擎。Apache Group在完成GNUJSP1.0的开 发之后,开始考虑在SUN的JSWDK基础上开发 一个可以直接提供Web服务的JSP服务器,当 然同时也支持Servlet,这样Tomcat就诞生了。 Tomcat是jakarta项目中的一个重要的子项目, 其被JavaWorld杂志的编辑选为2001年度最具 创新的java产品,同时它又是sun公司官方推荐 的servlet和jsp容器。
Tomcat源码解析
Http11Protocol 类完全路径 org.apache.coyote.http11.Http11Protocol,这是支 持HTTP的BIO实现。Http11Protocol包含了 JIoEndpoint对象及Http11ConnectionHandler对象。 Http11ConnectionHandler对象维护了一个 Http11Processor对象池,Http11Processor对象会 调用CoyoteAdapter完成HTTP Request的解析和分 派。 JIoEndpoint维护了两个线程,Acceptor请求接 收线程及Executor请求处理线程池。Acceptor是接 收Socket,然后从 Executor请求处理线程池中找出 空闲的线程处理socket,如果 Executor请求处理线 程池没有空闲线程,请求会被放入阻塞队列等待有 空闲线程。

tomcat9源码编译

tomcat9源码编译

tomcat9源码编译
编译 Tomcat 9 的源代码需要以下步骤:
1. 下载 Tomcat 9 的源代码,可以从 Apache Tomcat 官网下载。

2. 解压下载的源代码,可以使用命令行或者解压工具进行操作。

3. 配置 JDK 版本,Tomcat 9 需要使用 JDK 8 或更高版本,需要先安装对应版本的 JDK,并将其配置到环境变量中。

4. 进入 Tomcat 源代码目录下的 `bin` 目录,运行 `mvn clean install` 命令,这将会编译整个 Tomcat 源代码,并安装依赖项。

5. 编译完成后,可以在 `target` 目录下找到编译后的文件。

其中,`tomcat-juli.jar` 是Tomcat 的核心库,`tomcat-util.jar` 是Tomcat 的工具类库,`tomcat-coyote.jar`、`tomcat-jaspic.jar`、`tomcat-jni.jar` 等是 Tomcat 的其他组件库。

6. 将编译后的文件复制到 Tomcat 的 `lib` 目录下,覆盖原有的库文件即可使用自定义的 Tomcat。

注意事项:
* 在运行 `mvn clean install` 命令时,可能会遇到一些错误,需要根据错误提示进行修复。

* 在使用自定义的 Tomcat 时,需要注意与应用程序的兼容性。

tomcat架构及源码解析

tomcat架构及源码解析

很多开源应用服务器都是集成tomcat作为web container的,而且对于tomcat 的servlet container这部分代码很少改动。

这样,这些应用服务器的性能基本上就取决于Tomcat处理HTTP请求的connector模块的性能。

本文首先从应用层次分析了tomcat所有的connector种类及用法,接着从架构上分析了connector 模块在整个tomcat中所处的位置,最后对connector做了详细的源代码分析。

并且我们以Http11NioProtocol为例详细说明了tomcat是如何通过实现ProtocolHandler接口而构建connector的。

通过本文的学习,应该可以轻松做到将tomcat做为web container集成到第三方系统,并且自定义任何你想要的高性能的HTTP连接器1 Connector介绍1.1 Connector的种类Tomcat源码中与connector相关的类位于org.apache.coyote包中,Connector 分为以下几类:∙Http Connector, 基于HTTP协议,负责建立HTTP连接。

它又分为BIO Http Connector与NIO Http Connector两种,后者提供非阻塞IO与长连接Comet支持。

∙AJP Connector, 基于AJP协议,AJP是专门设计用来为tomcat与http 服务器之间通信专门定制的协议,能提供较高的通信速度和效率。

如与Apache服务器集成时,采用这个协议。

∙APR HTTP Connector, 用C实现,通过JNI调用的。

主要提升对静态资源(如HTML、图片、CSS、JS等)的访问性能。

现在这个库已独立出来可用在任何项目中。

Tomcat在配置APR之后性能非常强劲。

1.2 Connector的配置对Connector的配置位于conf/server.xml文件中。

SpringBoot内置Tomcat启动原理源码分析

SpringBoot内置Tomcat启动原理源码分析

SpringBoot内置Tomcat启动原理源码分析1、获取SpringBoot内置Tomcat⾃动配置类: 在SpringBoot项⽬中引⼊spring-boot-starter-web依赖,就默认使⽤Tomcat容器,该依赖中引⼊spring-boot-starter-tomcat、spring-webmvc,就引⼊了tomtcat核⼼依赖和springMvc相关jar包,这样就间接地引⼊了tomcat。

在执⾏SpringBoot项⽬启动类的main()⽅法,启动SpringBoot项⽬的过程中会加载各个jar包下META-INF/spring.factories的⽂件,在该⽂件中包含着⾃动配置的⼦路径,在refresh()⽅法中的invokeBeanFactoryPostProcessors()中⾸先会对启动类上的 @SpringBootApplication 注解进⾏解析,最终调⽤ AutoConfigurationImportSelector类中的 getAutoConfigurationEntry() 加载 META-INF/spring.factories ⽂件中的⾃动配置类,得到⾃动配置类的全路径,其中 org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration 为tomcat⾃动配置类。

具体加载流程见:protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}AnnotationAttributes attributes = getAttributes(annotationMetadata);// 1、得到META-INF/spring.factories⽂件中配置的所有⾃动配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 移除重复的配置类configurations = removeDuplicates(configurations);// 获取需要排除的⾃动配置类,eg:注解属性中的exculde的配置类Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 检查需要被排除的配置类,因为有些不是⾃动配置类,需要抛异常checkExcludedClasses(configurations, exclusions);// 移除需要排除的配置类configurations.removeAll(exclusions);// 根据 META-INF/spring-autoconfigure-metadata.properties 中配置的规则过虑掉⼀部分配置类(根据@ConditionalOnXXX注解进⾏过滤)configurations = getConfigurationClassFilter().filter(configurations);// 获取符合条件的配置类后,触发 AutoConfigurationImportEvent 事件fireAutoConfigurationImportEvents(configurations, exclusions);// 将符合条件和需要排除的配置类封装进 AutoConfigurationEntry 对象中返回return new AutoConfigurationEntry(configurations, exclusions);}2、ServletWebServerFactoryAutoConfiguration - tomcat⾃动配置类分析3、创建tomcat⼯⼚@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)static class EmbeddedTomcat {@BeanTomcatServletWebServerFactory tomcatServletWebServerFactory(ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,ObjectProvider<TomcatContextCustomizer> contextCustomizers,ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {// 创建⽣产tomcat的⼯⼚TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().collect(Collectors.toList()));factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().collect(Collectors.toList()));factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));return factory;}} 4、创建tomcat容器 在SpringBoot启动过程中会调⽤ AbstractApplicationContext.refresh() ⽅法,在该⽅法会调⽤onRefresh()⽅法,这个⽅法是个模板⽅法,最终会交给⼦类实现,在使⽤内置tomcat的SpringBoot项⽬中,最终会调⽤ ServletWebServerApplicationContext 实现(AbstractApplicationContext是GenericWebApplicationContext,ServletWebServerApplicationContext 是GenericWebApplicationContext),最终调⽤ServletWebServerApplicationContext 的createWebServer()⽅法创建 webServer。

Tomcat源码分析篇(转载)

Tomcat源码分析篇(转载)

Tomcat源码分析篇(转载)说明:仅供学习,原⽂出⾃Tomcat源码分析(⼀)--服务启动1. Tomcat主要有两个组件,连接器和容器,所谓连接器就是⼀个http请求过来了,连接器负责接收这个请求,然后转发给容器。

容器即servlet容器,容器有很多层,分别是Engine,Host,Context,Wrapper。

最⼤的容器Engine,代表⼀个servlet引擎,接下来是Host,代表⼀个虚拟机,然后是Context,代表⼀个应⽤,Wrapper对应⼀个servlet。

从连接器传过来连接后,容器便会顺序经过上⾯的容器,最后到达特定的servlet。

要说明的是Engine,Host两种容器在不是必须的。

实际上⼀个简单的tomcat只要连接器和容器就可以了,但tomcat的实现为了统⼀管理连接器和容器等组件,额外添加了服务器组件(server)和服务组件(service),添加这两个东西的原因我个⼈觉得就是为了⽅便统⼀管理连接器和容器等各种组件。

⼀个server可以有多个service,⼀个service包含多个连接器和⼀个容器,当然还有⼀些其他的东西,看下⾯的图就很容易理解Tomcat的架构了:2. ⼀个⽗组件⼜可以包含多个⼦组件,这些被统⼀管理的组件都实现了Lifecycle接⼝。

只要⼀个组件启动了,那么他的所有⼦组件也会跟着启动,⽐如⼀个server启动了,它的所有⼦service都会跟着启动,service启动了,它的所有连接器和容器等⼦组件也跟着启动了,这样,tomcat要启动,只要启动server就⾏了,其他的组件都会跟随着启动3. ⼀般启动Tomcat会是运⾏startup.bat或者startup.sh⽂件,实际上这两个⽂件最后会调⽤org.apache.catalina.startup.Bootstrap类的main⽅法,这个main⽅法主要做了两件事情,1:定义和初始化了tomcat⾃⼰的类加载器,2:通过反射调⽤了org.apache.catalina.startup.Catalina的process⽅法;4. process⽅法的功能也很简单,1:如果catalina.home和catalina.base两个属性没有设置就设置⼀下,2:参数正确的话就调⽤execute⽅法,execute的⽅法就是简单的调⽤start⽅法,其中在判断参数正确的⽅法arguments中会设置starting标识为true,这样在execute⽅法中就能调⽤start⽅法,start⽅法是重点,在它⾥⾯启动了我们的Tomcat所有的服务5. 这⾥最重要的⽅法是createStartDigester();和((Lifecycle) server).start();createStartDigester⽅法主要的作⽤就是帮我们实例化了所有的服务组件包括server,service和connect,⾄于怎么实例化的等下再看,start⽅法就是启动服务实例了。

tomcat 源码解读

tomcat 源码解读

tomcat 源码解读Tomcat 是一款流行的开源 Web 服务器和应用服务器,它基于Java 技术开发,支持多种 Web 应用程序和框架。

本文将带您深入解读 Tomcat 的源码,帮助您更好地理解 Tomcat 的工作原理和实现细节。

一、Tomcat 架构概述Tomcat 是一个基于 Java 的开源 Web 服务器和应用服务器,它由多个组件组成,包括 Web 容器、Servlet 容器、连接器、过滤器等。

其中 Web 容器和 Servlet 容器是 Tomcat 的核心组件,它们负责管理 Web 应用程序的部署和运行。

Tomcat 通过多线程技术实现了高效的处理请求和响应,同时还支持集群和负载均衡等高级功能。

二、源码解析1. Web 容器源码解析Web 容器是 Tomcat 的核心组件之一,它负责管理 Web 应用程序的部署和运行。

在 Tomcat 中,Web 容器使用 Servlet 技术实现,通过 Servlet API 和相关类库来处理 HTTP 请求和响应。

在源码中,Web 容器实现了 Servlet API 中的核心接口,如HttpServletRequest、HttpSession、ServletContext 等,同时还提供了 Web 应用程序所需的配置和部署功能。

2. Servlet 容器源码解析Servlet 容器是 Tomcat 中另一个核心组件,它负责管理Servlet 的部署和运行。

在源码中,Servlet 容器实现了 Servlet API 中的核心接口和类库,提供了对 Servlet 的管理和控制功能。

同时,Servlet 容器还实现了多线程技术,通过线程池来处理请求和响应,提高了系统的处理效率。

3. Tomcat 连接器源码解析Tomcat 的连接器负责与客户端进行通信,它包括 HTTP 连接器和AJP 连接器等。

在源码中,连接器实现了基于 TCP/IP 的通信协议,通过 socket 通信来接收和发送请求和响应数据。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

Tomcat的核心类图如下所示:Catalina:与开始/关闭shell脚本交互的主类,因此如果要研究启动和关闭的过程,就从这个类开始看起。

Server:是整个Tomcat组件的容器,包含一个或多个Service。

Service:Service是包含Connector和Container的集合,Service用适当的Connector接收用户的请求,再发给相应的Container来处理。

Connector:实现某一协议的连接器,如默认的有实现HTTP、HTTPS、AJP协议的。

Container:可以理解为处理某类型请求的容器,处理的方式一般为把处理请求的处理器包装为Valve对象,并按一定顺序放入类型为Pipeline的管道里。

Container有多种子类型:Engine、Host、Context和Wrapper,这几种子类型Container依次包含,处理不同粒度的请求。

另外Container里包含一些基础服务,如Loader、Manager和Realm。

Engine:Engine包含Host和Context,接到请求后仍给相应的Host在相应的Context里处理。

Host:就是我们所理解的虚拟主机。

Context:就是我们所部属的具体Web应用的上下文,每个请求都在是相应的上下文里处理的。

Wrapper:Wrapper是针对每个Servlet的Container,每个Servlet都有相应的Wrapper 来管理。

可以看出Server、Service、Connector、Container、Engine、Host、Context和Wrapper 这些核心组件的作用范围是逐层递减,并逐层包含。

下面就是些被Container所用的基础组件:Loader:是被Container用来载入各种所需的Class。

Manager:是被Container用来管理Session池。

Realm:是用来处理安全里授权与认证。

分析完核心类后,再看看Tomcat启动的过程,Tomcat启动的时序图如下所示:从上图可以看出,Tomcat启动分为init和start两个过程,核心组件都实现了Lifecycle接口,都需实现start方法,因此在start过程中就是从Server开始逐层调用子组件的start过程。

2)基于JMXTomcat会为每个组件进行注册过程,通过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管理各种组件的行为和生命期。

3)事件侦听各个组件在其生命期中会有各种各样行为,而这些行为都有触发相应的事件,Tomcat就是通过侦听这些时间达到对这些行为进行扩展的目的。

在看组件的init和start过程中会看到大量如:lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);这样的代码,这就是对某一类型事件的触发,如果你想在其中加入自己的行为,就只用注册相应类型的事件即可。

前几天分析了一下Tomcat的架构和启动过程,今天开始研究它的运转机制。

Tomcat最本质就是个能运行JSP/Servlet的Web服务器,因此最典型的应用就是用户通过浏览器访问服务器,Tomcat接收到请求后转发给Servlet,由Servlet处理完后,把结果返回给客户端。

今天就专门解析一下这么一个完整的请求的内部机理。

通过DEBUG,一路跟下来,发现Tomcat处理请求的核心过程是以下几点:∙启动的时候启动预支持协议的Endpoint,Endpoint会起专门的线程监听相应协议的请求,默认的情况下,会启动JIoEndpoint,JIoEndpoint基于Java ServerSocket接收Http的请求∙ServerSocket接收到客户端请求的Socket后,一路包装,并一路从Host一直传递到Wrapper,再请求到相应的Servlet下面将重点解析以上两个过程。

通过以前的分析(Tomcat源码分析一)可知道当Tomcat启动的时候会启动Connector,此时Connector会通过ProtocolHandler把Endpoint启动起来。

默认情况下,Tomcat会启动两种Connector,分别是Http协议和AJP协议的,依次对应Http11Protocol和AjpProtocol,两者都是启动JIoEndpoint。

下面看看JIoEndpoint的start方法:[java]view plaincopyprint?1. p ublic void start() throws Exception {2. // Initialize socket if not done before3. if (!initialized) {4. init();5. }6. if (!running) {7. running = true;8. paused = false;9. // Create worker collection10. if (getExecutor() == null) {11. createExecutor();12. }13. // Start acceptor threads14. for (int i = 0; i < acceptorThreadCount; i++) {15. Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);16. acceptorThread.setPriority(threadPriority);17. acceptorThread.setDaemon(getDaemon());18. acceptorThread.start();19. }20. }21. }public void start() throws Exception {// Initialize socket if not done beforeif (!initialized) {init();}if (!running) {running = true;paused = false;// Create worker collectionif (getExecutor() == null) {createExecutor();}// Start acceptor threadsfor (int i = 0; i < acceptorThreadCount; i++) {Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);acceptorThread.setPriority(threadPriority);acceptorThread.setDaemon(getDaemon());acceptorThread.start();}}}以上代码很清晰地表示启动acceptorThreadCount个线程,每个线程由Acceptor代理,具体看看Acceptor的run方法:[java]view plaincopyprint?1. p ublic void run() {2. // Loop until we receive a shutdown command3. while (running) {4. // Loop if endpoint is paused5. while (paused) {6. try {7. Thread.sleep(1000);8. } catch (InterruptedException e) {9. // Ignore10. }11. }12. // Accept the next incoming connection from the server socket13. try {14. Socket socket = serverSocketFactory.acceptSocket(serverSocket);15. serverSocketFactory.initSocket(socket);16. // Hand this socket off to an appropriate processor17. if (!processSocket(socket)) {18. // Close socket right away19. try {20. socket.close();21. } catch (IOException e) {22. // Ignore23. }24. }25. }catch ( IOException x ) {26. if ( running ) log.error(sm.getString("endpoint.accept.fail"), x);27. } catch (Throwable t) {28. log.error(sm.getString("endpoint.accept.fail"), t);29. }30. // The processor will recycle itself when it finishes31. }32. }public void run() {// Loop until we receive a shutdown commandwhile (running) {// Loop if endpoint is pausedwhile (paused) {try {Thread.sleep(1000);} catch (InterruptedException e) {// Ignore}}// Accept the next incoming connection from the server sockettry {Socket socket =serverSocketFactory.acceptSocket(serverSocket);serverSocketFactory.initSocket(socket);// Hand this socket off to an appropriate processorif (!processSocket(socket)) {// Close socket right awaytry {socket.close();} catch (IOException e) {// Ignore}}}catch ( IOException x ) {if ( running ) log.error(sm.getString("endpoint.accept.fail"), x);} catch (Throwable t) {log.error(sm.getString("endpoint.accept.fail"), t);}// The processor will recycle itself when it finishes}}由此可得到这么一个结论:Tomcat就是通过ServerSocket监听Socket的方式来接收客户端请求的。

相关文档
最新文档