首页 > 其他分享 >Tomcat_实现内嵌代码方式启动

Tomcat_实现内嵌代码方式启动

时间:2024-01-20 19:12:39浏览次数:25  
标签:内嵌 20 Tomcat tomcat 代码 2024 apache org

构建tomcat_maven项目

可以从github上直接拉取tomcat_maven项目;也可以自己下载源码构建,这里贴一下tomcat8对应的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.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </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</version>
        </dependency>
        <dependency>
            <groupId>org.easymock</groupId>
            <artifactId>easymock</artifactId>
            <version>3.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

tomcat启动方式

启动方式有两种,一种是下载tomcat安装包,运行bin/start.sh独立启动;另一种是类似springboot,内嵌tomcat代码作为web容器启动

内嵌方式启动

tomcat测试代码里依赖的就是内嵌方式启动,所以看一下测试函数是如何实现的即可,具体代码位置在,test/org/apache/catalina/startup/TestTomcat.java

@Test
public void testProgrammatic() throws Exception {
    Tomcat tomcat = getTomcatInstance();

    // No file system docBase required
    Context ctx = tomcat.addContext("", null);

    Tomcat.addServlet(ctx, "myServlet", new HelloWorld());
    ctx.addServletMapping("/", "myServlet");

    tomcat.start();

    ByteChunk res = getUrl("http://localhost:" + getPort() + "/");
    assertEquals("Hello world", res.toString());
}

我们知道Tomcat是按层级构建的,server -> services -> connectors, engine -> hosts -> contexts -> wrappers ,独立启动时可以依赖解析xml实现,现在关注如何通过代码配置完成构建,这里核心类就是Tomcat了
在测试的基础类中,test/org/apache/catalina/startup/TomcatBaseTest.java ,简单看一下官方测试是如何构建Tomcat实例

tomcat = new TomcatWithFastSessionIDs();
String protocol = getProtocol();
Connector connector = new Connector(protocol);
// Listen only on localhost
connector.setAttribute("address", InetAddress.getByName("localhost").getHostAddress());
// Use random free port
connector.setPort(0);
// Mainly set to reduce timeouts during async tests
connector.setAttribute("connectionTimeout", "3000");
tomcat.getService().addConnector(connector);
tomcat.setConnector(connector);
...

内嵌构建

尝试直接调用Tomcat生命周期函数完成Tomcat类的构建与使用,这里需要提一下Lifecycle,里面定义了tomcat组件的生命周期,例如初始化,启动..

Tomcat tomcat = new Tomcat();
tomcat.setBaseDir("xx");
tomcat.init();
tomcat.start();
tomcat.stop();
tomcat.destroy();

一月 20, 2024 6:30:03 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:30:03 下午 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
一月 20, 2024 6:30:03 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Tomcat
一月 20, 2024 6:30:03 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:30:03 下午 org.apache.coyote.AbstractProtocol pause
信息: Pausing ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:30:03 下午 org.apache.catalina.core.StandardService stopInternal
信息: Stopping service Tomcat
一月 20, 2024 6:30:03 下午 org.apache.coyote.AbstractProtocol stop
信息: Stopping ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:30:03 下午 org.apache.coyote.AbstractProtocol destroy
信息: Destroying ProtocolHandler ["http-nio-8080"]

代码很简单,init()方法里已经创建了tomcat的server、service和connector组件;web应用的engine,host.. 等组件还未创建,而且还需要有一个可以测试的servlet,下面的测试代码写在官方测试目录下

@Test
public void test() throws LifecycleException, InterruptedException, IOException {
    Tomcat tomcat = new Tomcat();
    tomcat.setBaseDir("xx");
    Context ctx = tomcat.addContext("", null);
    OK ok = new OK();
    Tomcat.addServlet(ctx, "ok", ok);
    ctx.addServletMapping("/", "ok");

    tomcat.init();
    tomcat.start();
    ByteChunk res = TomcatBaseTest.getUrl("http://localhost:8080/");
    assertEquals("OK", res.toString());

    tomcat.stop();
    tomcat.destroy();
}

private static class OK extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/plain");
        resp.getWriter().print("OK");
    }
}

可以看到,这里创建了Context,同时绑定了一个返回OK字符的Servlet;创建context时会顺带完成host <- engine <- service <- server的构建,connector还是交由init()方法创建,测试日志如下

一月 20, 2024 6:38:19 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:38:19 下午 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
一月 20, 2024 6:38:19 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Tomcat
一月 20, 2024 6:38:19 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/@VERSION@
一月 20, 2024 6:38:19 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:38:39 下午 org.apache.coyote.AbstractProtocol pause
信息: Pausing ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:38:39 下午 org.apache.catalina.core.StandardService stopInternal
信息: Stopping service Tomcat
一月 20, 2024 6:38:39 下午 org.apache.coyote.AbstractProtocol stop
信息: Stopping ProtocolHandler ["http-nio-8080"]
一月 20, 2024 6:38:39 下午 org.apache.coyote.AbstractProtocol destroy
信息: Destroying ProtocolHandler ["http-nio-8080"]

到这里,内嵌代码方式启动tomcat已经介绍完了,更多 关于springboot如何配置tomcat,会涉及到SCI接口,spring生命周期与tomcat生命周期的绑定.. 是一个更大的话题了。

标签:内嵌,20,Tomcat,tomcat,代码,2024,apache,org
From: https://www.cnblogs.com/snowsteps/p/17976990

相关文章

  • [译] kubernetes:kube-scheduler 调度器代码结构概述
    本文翻译自https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduling_code_hierarchy_overview.md译者:胡云Troy调度器代码层次结构概述介绍调度器监视新创建的还没有分配节点的Pod。当发现这样的Pod后,调度器将Pod调度到最......
  • 代码随想录 day25 组合总和Ⅲ 电话号码的字母组合
    组合总和Ⅲ跟组合总和Ⅰ很像这里固定了是1-9的范围而且确定了取k个数字那么就是确定了树的高度和宽度注意一下回溯的写法和边界条件就好还有剪枝操作如下其实就是当sum已经大于n就不需要再进行了电话号码的字母组合这题就是一般的回溯问题难点其实是在这投影怎么......
  • VisualStudioCode 代码对齐
    VisualStudioCode(简称VSCode)提供了多种方法来实现代码的对齐:1.内置对齐功能:通过快捷键`Shift+Alt+F`可以对当前选中文本进行对齐。这个方法适合于对单个区域进行快速对齐的情况。2.安装插件以实现自动对齐:VSCode有多个插件支持自动对齐功能,例如"Beautify"......
  • 代码之外:工程师的成长进阶秘籍
    程序员只懂技术能行吗? 为什么说技术人员“说”和“写”总得擅长一个? 你以为的“关注结果”是真的结果吗? 从一线工程师跃升团队管理者一共分几步? 在不断变化的职场环境中,技术人如何保持竞争力并实现自我增值,是摆在每个人面前的挑战。无论是一线工程师还是技术管理者,如......
  • 代码随想录 day24 回溯初体验
    组合熟悉一下回溯算法的基本流程以下是未曾进行剪枝处理的代码为什么要进行剪枝呢因为有一些情况是显然不可能成立的如下既然要取4个元素那么当取了1个元素之后集合剩余的元素不足4个不可能满足要求直接舍去具体边界思考路径剪枝代码如下......
  • TBK-RD8T3x 开发板 与1.77' 160(RGB)×128 代码
    TBK-RD8T3x开发板是一款基于增强型的高速1T8051内核的工业级集成触控按键功能的Flash微控制器。它支持多种通信接口,如GPIO、I2C、SPI等。以下是使用GPIO接口控制1.77'160(RGB)×128的代码:#include"tbkrd8t3x.h"voidmain(){//初始化TBK-RD8T3x开发板tbk_rd8t3x_in......
  • 详解匿名函数递归:从此能看懂天书代码
    最近在读《左耳听风》,里面提到了一个匿名函数递归的例子,觉得很有趣,但是我觉得书里讲解的还是有点难懂,所以尝试用自己的理解把这个问题重新讲了一遍。注:本文中所用的代码示例会同时使用JavaScript,Python语言。让我们先来看下面这段代码://javascript(f=>f(f))(f=>n=>n==......
  • Yuan2.0代码主要结构概览及三种并行方式实现
    该代码结构如下图所示:在initialize_megatron初始化megatron的过程中,有关于数据并行、流水线并行、张量并行的实现,简介及其实现如下:模型分布式环境初始化:以两台分别有8个GPU服务器为例,训练具有12层的transformerlayers,图一图二  本示例将模型纵向切割为4部分,每部分3......
  • [代码随想录] 第九天
    232.栈实现队列[https://leetcode.cn/problems/implement-queue-using-stacks/description/]思路:无classMyQueue{Stack<Integer>stackIn;Stack<Integer>stackOut;inttemp;publicMyQueue(){stackIn=newStack<>();......
  • [代码随想录] 第八天
    28.找出字符串中第一个匹配项的下标[https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/]思路:KMP算法,重点在于求NEXT数组。还不能理解..暂时先背下来了。classSolution{publicintstrStr(Stringhaystack,Stringneedle......