首页 > 其他分享 >springboot内嵌tomcat的实现原理

springboot内嵌tomcat的实现原理

时间:2024-05-12 22:20:54浏览次数:16  
标签:内嵌 springboot tomcat servlet Context Coyote import Servlet

目录

一、tomcat运行原理的简单分析

tomcat运行时可以简单分成两个大的模块,

(1) 负责处理socket连接并转换成request对象的部分,连接器Coyote

(2) 处理用户的请求的容器Catalina

下面简单介绍下这两个部分

1.1 Coyote

Coyote是tomcat的连接器框架的名称,是tomcat服务器提供的供客户端访问的外部接口。客户端通过Coytote与服务器建立连接,发送请求并接收响应。

Coyote封装了底层的网络通信(Scoket),为Catalina容器提供了统一的接口。Coyote将Scoket输入转换封装为Request对象交给Catalina处理,容器处理完后通过Coyote提供的Response对象将结果写入输出流中。

Coyote由如下几个部分组成。

EndPoint: Coyote通信端点,对scoket链接进行处理。

Processor: 把scoket连接中的信息转成Request对象(并不是Servlet规范中的请求对象)

Adapter: 把Request对象转换成Servlet规范中的ServletRequest

1.2 容器 catalina

Catalina是Servlet容器的实现,由Server,Service,Container组成了一个分层结构

Tomcat设计了四种容器,从大到小是父子关系,Engine,Host,Context,Wrapper。

Engine: 一个Service中只能有一个Engine

Host: 虚拟主机,一个Engine中可配置多个Host,通过配置不同的host可以在同一tomcat上部署不同的站点

Context: 表示一个应用,一个host中可以配置多个Context

Wrapper:表示一个Servlet,一个Context中可以有多个Servlet

Tomcat这些组成部分之间的关系都可以在server.xml中找到对应的标签。

二、用编码的方式启动tomcat

这一节用java代码来启动tomcat

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.Set;

public class TomcatTest {
    public static void main(String[] args) throws IOException, LifecycleException {
        //创建Tomcat对象
        Tomcat tomcat = new Tomcat();
        //设置基础目录的名称,这个名称并不是磁盘上真正存在的目录
        tomcat.setBaseDir("tomcat");
        //一个Context表示一个应用,给tomcat中设置一个应用的目录就是添加一个项目,这个目录需要真实存在
        File docBase = Files.createTempDirectory("boot.").toFile();
        // 第一个参数表示应用的访问路径,给空表示用根路径访问项目
        Context context = tomcat.addContext("", docBase.getAbsolutePath());
        // 利用Servlet规范中的ServletContainerInitializer接口给Context中添加Servlet,
        // Servlet容器启动时会执行被添加的ServletContainerInitializer接口中的onStartup方法
        context.addServletContainerInitializer(new ServletContainerInitializer() {
            @Override
            public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
                ServletRegistration.Dynamic dynamic = ctx.addServlet("hello", new HttpServlet() {
                    @Override
                    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                        resp.getWriter().println("<h1>hello tomcat</h1>");
                    }
                });
                dynamic.addMapping("/hello");
            }
        }, Collections.emptySet());

        //创建连接器
        Connector connector = new Connector("HTTP/1.1");
        connector.setPort(8080);
        //把连接器设置到tomcat上
        tomcat.setConnector(connector);
        //启动tomcat
        tomcat.start();
    }
}

这样就实现了以编码的方式启动一个Tomcat服务,并注册了一个servlet到应用中。

在springboot工程中,spring容器AnnotationConfigServletWebServerApplicationContext 的onRefresh方法中

有类似上边代码的逻辑,用编程的方式启动了一个tomcat。

关于这一点可以看下我的另一篇文章springboot的启动原理和流程

标签:内嵌,springboot,tomcat,servlet,Context,Coyote,import,Servlet
From: https://www.cnblogs.com/chengxuxiaoyuan/p/18188298

相关文章

  • Springboot自动配置原理
    在SpringBoot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan其中@EnableAutoConfiguration是实现自动化配置的核心注解。该注解通过@Import注解导入对应的配......
  • 从零手写实现 tomcat-11-filter 过滤器
    创作缘由平时使用tomcat等web服务器不可谓不多,但是一直一知半解。于是想着自己实现一个简单版本,学习一下tomcat的精髓。系列教程从零手写实现apacheTomcat-01-入门介绍从零手写实现apacheTomcat-02-web.xml入门详细介绍从零手写实现tomcat-03-基本的socket实......
  • SpringBoot速记
    本篇以SpringBoot快速构建一个基础项目,在构建的同时记录相关的知识。常见的架构图: 其中,config中可以引入第三方的jar包controller中存放控制类一个简单的例子如下: mapper中存放对数据库的操作接口 pojo中是实体对象类,常与数据表对应 service中存放服务类:......
  • SpringBoot3集成WebSocket
    标签:WebSocket,Session,Postman。一、简介WebSocket通过一个TCP连接在客户端和服务器之间建立一个全双工、双向的通信通道,使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据,在WebSocket的API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创......
  • __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法 AT&T ASM Syntax
    1Overview 开发一个OS,尽管绝大部分代码只需要用C/C++等高级语言就可以了,但至少和硬件相关部分的代码需要使用汇编语言,另外,由于启动部分的代码有大小限制,使用精练的汇编可以缩小目标代码的Size。另外,对于某些需要被经常调用的代码,使用汇编来写可以提高性能。所以我们必须了解汇......
  • springboot的链路日志
    1.背景在开发银行项目的时候有一个生成项目链路日志的需求。所谓的链路日志就是一个请求会经过多个项目的接口调用,它把这个请求内调用到的所有请求通过全局id串起来,通过全局id可以把所有涉及到的系统日志都快速的定位出来,方便线上出现问题时去排查问题。2.实现......
  • springboot使用log4j监控日志发送邮件
    实现log4j发送邮件功能大致流程:1、开启邮箱SMTP服务,获取SMTP登录密码2、引入javax.mail、javax.activation依赖3、配置log4j文件,指定邮件发送方和接收方以及发送方账号密码等4、重写SMTPAppender(不重写也能实现邮件发送功能)开启邮箱SMTP服务这里以qq邮......
  • springboot项目服务器访问速度慢-可能的解决方法
    springboot项目部署在服务器后,访问很慢或无法访问问题使用宝塔界面,尝试将打包后的jar包部署在服务器上运行时,发现访问速度不是很快,或者是直接访问不到。访问不到对应端口的springboot服务80端口也无法访问首次访问加载慢的解决方法修改jre文件找到安装的jre目......
  • Springboot Data Jdbc中Contains和Containing的用法
    Contains和Containing的用法privateStringtitle;privateList<String>tags;//查询标题包含指定字符串的书籍List<Book>findByTitleContains(Stringtitle);//查询包含指定标签的书籍List<Book>findByTagsContaining(Stringtag);--查询标题包含"Spring"的书......
  • 从零手写实现 tomcat-09-servlet 处理类
    创作缘由平时使用tomcat等web服务器不可谓不多,但是一直一知半解。于是想着自己实现一个简单版本,学习一下tomcat的精髓。系列教程从零手写实现apacheTomcat-01-入门介绍从零手写实现apacheTomcat-02-web.xml入门详细介绍从零手写实现tomcat-03-基本的socket实......