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. mysql 数据库 数组类型转换_mysql数字类型的数据如何进行转换?
  2. 图灵2010.06书讯
  3. iphone7wifi模块多少钱_模块炉价格参差不齐,消费者应独具慧眼!
  4. Spring事务传播行为7种类型 --- 看一遍就能记住!
  5. JAVA IO基本知识
  6. 【Spring】SpringBoot 如何使用JMX
  7. html onblur 函数执行了2次,JavaScript“onblur事件”调用函数失效 原因与解决方法
  8. 物理学基石 —— 麦克斯韦方程组
  9. win7 64位Apache http server+PHP配置
  10. linux(rhel) rescue修复详解
  11. 独家出品 | 培训机构免费资源汇总
  12. 腾讯收购Foxmail的意图
  13. 水下超声波测距c语言程序,超声波测距51C程序
  14. python 英语翻译_Python 实现中英文翻译
  15. 知识图谱实战开发案例剖析(22)Protege开发环境安装部署
  16. 【MySQL】删除记录
  17. 手风琴效果(js版本以及jquery版本)
  18. java启动器_Minecraft Java版新启动器正式开放
  19. Office 被曝 0 day 漏洞,微软确认 Windows 支持诊断工具存在问题;台半导体厂主管薪水大涨,超 10 人跻身亿元俱乐部
  20. 【知识兔】Excel教程 函数office软件 Excel素材 Excel网课 Excel入门

热门文章

  1. Ros-Bot在全屏和4k屏下怎样兼容
  2. 【专业扫盲】集成电路领域的核心会议与期刊
  3. Docker入门教程(详细)
  4. Python中Gevent的使用
  5. 这六个记账APP你的口袋里有吗?
  6. ANSYS APDL 瞬态分析-施加任意函数形式载荷
  7. 微信公众平台升级9大高级接口功能解读
  8. Smark Link 双上行组网,断开环路
  9. FFmpeg和SDL教程(五):同步视频
  10. 用微信小程序模拟圣诞的效果(雪花飘落)