1. 简介

spring boot的嵌入式容器用起来很爽,所以博主也想搞一个类似可以不依赖外部容器的轮子.

虽然可以直接用maven的插件 tomcatX-maven-plugin  完成,但是高版本的更新太慢,所以有了以下的轮子.

2. tomcat结构介绍

为什么要先放这张图嗯,因为嵌入式的tomcat API 设计也是按照这个结构设计的.博主并不想看他的API文档,想靠这张图猜一下他的API如何使用.

3 maven坐标引入

        <dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>8.5.34</version></dependency>

这里选择了热门的tomcat8.5

4 . 入门demo

首先作为入门级的demo当然是要简单,目录结构如下

其中MyWeb 这个类是一个非常简单的servlet 测试类,代码如下

public class MyWeb extends HttpServlet {@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {res.setCharacterEncoding("utf-8");System.out.println("进入请求");PrintWriter writer = res.getWriter();writer.println("<h1>HttpServlet request</h1>");}
}

问题1:为什么我要在target目录下创建WEB-INF

嵌入式的tomcat有2种加载servlet的模式

1. 直接从代码里创建对象,加入容器

2.和外部的tomcat一样,从WEB-INF目录下的web.xml文件中加载,这里我把 target目录当做应用根目录,自然要手动创建.当然也可以手动指定web.xml的路径,这里后面会提及.

=================框架准备好.撸起袖子就是干我是分割线======================================

通过上面的结构图发现,:

tomcat下有一个server,一个server下有多个service,然后一个service下有多个connector(连接器,用于接收请求),一个Container(正真处理请求的)

同样的结构在tomcat的 conf/server.xml 配置文件里也可以体现

其中配置文件里的Engine就是Container

根据这个关系,可以构建一个最简单的项目结构

        Tomcat tomcat = new Tomcat();//Server server = tomcat.getServer();//看源码发现,他只能设置一个service,直接拿默认的Service service = tomcat.getService();//创建连接器,并且添加对应的连接器,同时连接器指定端口Connector connector = new Connector();connector.setPort(8888);service.addConnector(connector);//创建一个引擎,放入service中Engine engine = new StandardEngine();service.setContainer(engine);engine.setDefaultHost("localhost");engine.setName("myTomcat");//添加hostHost host = new StandardHost();engine.addChild(host);host.setName("localhost");host.setAppBase("webapps");

别看API挺多,其实对照着 server.xml 文件可以很轻易写出来,

然后就是把我们的项目挂载上去了.

用过tomcat都知道,tomcat的挂载方式,这里我们也对应把xml文件翻译成对应的java代码

<Host><Context path="/前缀" docBase="项目路径" reloadable="true开启热更新">
</Host>
//在对应的host下面创建一个 context 并制定他的工作路径,会加载该目录下的所有class文件,或者静态文件StandardContext context = (StandardContext) tomcat.addContext(host, "/", "/Users/bignosecat/IdeaProjects/xx/tomcat/target");//初始化ContextConfig配置context.addLifecycleListener(new ContextConfig());

这里我直接把我整个项目的编译路径当做项目路径挂载去了tomcat

最后把自己写的servlet加入进去.

 //创建一个servletWrapper myservlet = new StandardWrapper();myservlet.setServlet(new MyWeb());myservlet.setName("myServlet");//把servlet加入到contxt中context.addChild(myservlet);
//这里注意,要先添加到contxt中在映射路径,不然会空指针myservlet.addMapping("/chyweb1");

最后一步启动tomcat

//tomcat启动
tomcat.start();
//保持主线程不退出
tomcat.getServer().await();

测试浏览器输入

http://127.0.0.1:8888/chyweb1

到这里最简单的demo完成.

5.静态文件的加载

上面的demo只能处理一个自定义的servlet.而且不能处理jsp以及静态文件.

现在在项目路径下有一个 test.html的静态文件.按照以前tomcat的使用习惯,我在浏览器输入

http://127.0.0.1:8888/test.html

应该可以加载出这个html文件的对应信息,结果出现的是404.

如果熟悉tomcat可以知道,tomcat有个默认的servlet用来处理静态请求.还有一个专门处理jsp的servlet

通过源码分析,发现他还是提供了加载默认的servlet

 context.addLifecycleListener(tomcat.getDefaultWebXmlListener());

使用上面这个API可以在初始化的时候加载上面标注出来的方法.

因为现在项目都在逐渐去除JSP,使用前后端分离,所以我这里就手动添加默认的servlet,而不引入jsp的servlet

//创建一个默认的Servlet 用来处理 html 等静态资源,如果上面设置了getDefaultWebXmlListener 可以不添加Wrapper defaultServlet = new StandardWrapper();defaultServlet.setServlet(new DefaultServlet());defaultServlet.setName("default");context.addChild(defaultServlet);defaultServlet.addMapping("/");

添加该servlet后重启项目,再次运行

http://127.0.0.1:8888/test.html

6. web.xml加载

这里如果使用手动添加servlet的方式,每次都很麻烦,而且代码耦合性太大,所以想能不能去像以前一样读web.xml文件.然后加载对应的servlet

通过源码分析发现加入以下配置即可

//初始化ContextConfig配置
context.addLifecycleListener(new ContextConfig());

但是只能在项目路径下的 WEB-INF/web.xml 文件

嗯果然还是tomcat的老套路,但是我就想随意定义web.xml怎么办

博主又在源码中找找找发现

从这段代码中发现,那我只要给他设上值不就可以了吗.

so加入

        context.getServletContext().setAttribute("org.apache.catalina.deploy.alt_dd",
"/Users/bignosecat/IdeaProjects/xx/tomcat/src/main/resources/web.xml");

然后我访问了这个web.xml中定义的路径,成功

7. 完整的嵌入Tomcat 启动代码

 Tomcat tomcat = new Tomcat();//Server server = tomcat.getServer();//看源码发现,他只能设置一个service,直接拿默认的Service service = tomcat.getService();//创建连接器,并且添加对应的连接器,同时连接器指定端口Connector connector = new Connector();connector.setPort(8888);service.addConnector(connector);//创建一个引擎,放入service中Engine engine = new StandardEngine();service.setContainer(engine);engine.setDefaultHost("localhost");engine.setName("myTomcat");//添加hostHost host = new StandardHost();engine.addChild(host);host.setName("localhost");host.setAppBase("webapps");//在对应的host下面创建一个 context 并制定他的工作路径StandardContext context = (StandardContext) tomcat.addContext(host, "/", "/Users/bignosecat/IdeaProjects/xx/tomcat/target");//初始化ContextConfig配置context.addLifecycleListener(new ContextConfig());//加载指定位置的web.xml//context.getServletContext().setAttribute("org.apache.catalina.deploy.alt_dd","/Users/bignosecat/IdeaProjects/xx/tomcat/src/main/resources/web.xml");//初始化 默认的servlet,这里会 触发tomcat#initWebappDefaults 方法,等价于平时tomcat自动加载默认的conf/web.xml文件//当然也可以手动加载,这里因为我没引用jsp的包,所以不自动加载.context.addLifecycleListener(tomcat.getDefaultWebXmlListener());//创建一个默认的Servlet 用来处理 html 等静态资源,如果上面设置了getDefaultWebXmlListener 可以不添加Wrapper defaultServlet = new StandardWrapper();defaultServlet.setServlet(new DefaultServlet());defaultServlet.setName("default");context.addChild(defaultServlet);defaultServlet.addMapping("/");//创建一个servletWrapper myservlet = new StandardWrapper();myservlet.setServlet(new MyWeb());myservlet.setName("myServlet");context.addChild(myservlet);myservlet.addMapping("/chyweb1");//tomcat启动tomcat.start();//保持主线程不退出tomcat.getServer().await();

8. 整合springmvc

O__O "…,这个还需要整合吗.直接把springmvc的web.xml 加载进嵌入tomcat 就可以了.

9.嵌入tomcat封装

这里博主把这API封装了一道,用于方便调用.代码具体看下面github,下面只演示API的使用

github
gitee​​​​​​​

下面是这个框架的使用介绍

测试项目路径如下(一个最简单的springmvc项目):

在github获取项目后,安装进maven 引入坐标

       <dependency><groupId>chy.frame</groupId><artifactId>tomcat</artifactId><version>1.0-SNAPSHOT</version></dependency>

在Main中写入然后直接运行即可

  public static void main(String[] args) {/***  构造有3个参数*  1. tomcat的端口*  2. web.xml的路径*  3. 项目静态文件的路径* 路径可以写 绝对路径或者*  classpath: 开头 在classes路径下寻找*  projectpath: 开头 在项目路径下寻找*  */ ChyTomcat chyTomcat = new ChyTomcat(8001,"classpath:web.xml","projectpath:static");//服务开启chyTomcat.start();}

成功启动tomcat,并访问成功所定义的请求

嵌入式tomcat分析,并手写加载springMvc相关推荐

  1. Tomcat(二):手写嵌入式tomcat

    一.什么是嵌入式tomcat 嵌入式tomcat:非传统的部署方式,将tomcat嵌入到主程序中进行运行. 二.嵌入式tomcat的优点 灵活部署.任意指定位置.通过复杂的条件判断 三.Maven集成 ...

  2. 嵌入式系统串口解析二进制数_嵌入式系统Bootloader分析及DSP56F800串口加载功能实现...

    嵌入式系统 Bootloader 分析及 DSP56F800 串口加载功 能实现 张小平 ; 谷勇 ; 丰新龙 [期刊名称] <海军航空工程学院学报> [年 ( 卷 ), 期] 2010( ...

  3. Vue3.0+Cesium+Tomcat服务下倾斜摄影数据加载详细过程

    Vue3.0+Cesium+Tomcat服务下倾斜摄影数据加载 1.Vue-cli 3.0 + cesium 构建 参考资料地址Vue-cli 3.0 + cesium 构建 注意,因为文档中设置默认 ...

  4. android去广告实现原理,分析某视频软件加载方案和去广告原理

    分析某视频软件加载方案和去广告原理0x1用到的工具:AndroidKiller eclipse jd-gui Android逆向助手0x2拿到APK后首先想到的是是否有签名验证,因此用逆向助手重新签名 ...

  5. js如何在当前页面加载springmvc返回的页面_手写SpringMVC学习

    前面我们学习了spring框架源码,做了一些自己手写的学习,最近,我们开始学习springMVC框架的学习 ,springMVC框架,相信大家不陌生了,所以这里不做过多的介绍了. SpringMVC以 ...

  6. redis 启动加载mysql_Redis分析系列:启动加载过程

    从本篇文章开始(命名为Redis分析系列),将会通过分析Redis的源代码(以Redis 2.2.0 RC1为准),来对它的内部实现做一些探讨.本文主要介绍Redis启动加载过程,总体上可以分为如下几 ...

  7. tomcat 热部署、热加载 精析

    1.前言 找了很多篇文章,没有一篇文章讲的清晰.明了,很多人只是会用,但不是能真正说明白,这年头找个懂理论的,真难! 2.热部署 原定义:tomcat处于运行状态时,能够监测webapps下的文件,如 ...

  8. Myabtis源码分析五-Mybatis配置加载完全图解,建造者模式的使用,涵盖Java各种技术栈

    private SqlSessionFactory sqlSessionFactory; @Before public void init() throws IOException { //----- ...

  9. war包放到webapps下,启动tomcat,tomcat正常,却无法加载项目

    由于工作需要,打war包,放到webapps下,启动tomcat,地址栏输入项目路径报错404 1.先确认tomcat是否正常启动:可以正常显示tomcat的图标,tomcat正常启动. 2.查看to ...

最新文章

  1. 生产环境实用的小脚本
  2. 【Redis高手修炼之路】客户端工具——客户端工具以及常用命令
  3. 控制系统状态空间表达式的解(1)——求解线性定常系统零输入响应
  4. 球体重量在线计算机,用图形计算器研究热气球.doc
  5. 各家关节机器人示教器特点
  6. IIS5.1完整安装包使用指南(详解版)
  7. 基础 | 并发编程 - [LongAdder Striped64]
  8. 【数据分析自学】一、系统认识数据分析
  9. SAP中采购合同与采购计划协议关联性分析
  10. ps抠图——抠出自己想要的素材(钢笔工具的使用)
  11. 富士康员工的逆袭之路,从月薪4K到现在月入1W+,是如何做到的?
  12. HTTP报文是什么样的?
  13. oracle中那个日期怎么相减_oracle日期时间加减规则
  14. 关于使用开发企业内部应用需要前端调起企业微信JS-SDK的一些坑
  15. c语言0的作用是什么意思,C语言 1 0 是什么意思
  16. SuperMap 的介绍和基本使用
  17. 锁屏状态下NFC不可用
  18. 小程序bindtap和cachetap的区别
  19. 听说你还在点击图片,然后鼠标右键设置电脑壁纸,小编教你如何实现自动更换电脑壁纸操作
  20. 数据挖掘,什么是数据挖掘?

热门文章

  1. sql server修改数据库排序规则
  2. 学生党毕业论文福利,参考文献的排版方法(利用bib文件的方式)
  3. 基于构件开发的应用框架设计
  4. SAP VK11税码的理解
  5. 单机存储引擎到mysql的思考三
  6. 阿里体育CEO张大钟卸任:与大文娱融合打通 戴玮兼任
  7. Python初级入门:一、编写程序的基本步骤
  8. Kubernetes(三)—操作可视化管理界面
  9. 【5】Maxwell轴向电机怎样调用出波形的FFT傅立叶分析图
  10. 【程序媛晒83行代码】单身狗汪化翻译机,把你的话都变成汪星语