SpringBoot集成Tomcat服务
使用的成本越低,内部封装越复杂;
一、Tomcat集成
1、依赖层级
在SpringBoot框架的web依赖包中,引入的是内嵌Tomcat组件,基于SpringBoot的版本,Tomcat集成的是9.0版本;
<!-- 1、项目工程依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<!-- 2、starter-web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.2.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- 3、starter-tomcat依赖 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.31</version>
<scope>compile</scope>
</dependency>
2、自动化配置
在SpringBoot框架的自动配置类中,Web项目中不显式更换其他服务依赖时,默认提供了对Tomcat服务的管理;
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
ServletWebServerFactoryConfiguration.EmbeddedTomcat.class})
public class ServletWebServerFactoryAutoConfiguration {
@Bean
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
ServerProperties serverProperties) {
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
}
}
二、Tomcat架构

Server:代表整个Tomcat容器;
Service:服务器内部的中间组件,将一个或多个Connector绑定到一个Engine上;
Engine:表示特定服务的请求处理管道,接收Connector的请求并响应;
Host:网络主机名称;
Connector:连接器处理与客户端的通信;
Context:代表一个Web应用程序的上下文;
参考Tomcat9.0版本的核心组件描述,对于框架有大致的了解后,再去分析集成原理,会更容易把握主线逻辑;
三、Tomcat配置
1、基础配置
在配置文件中,对Tomcat做一些基础性的设置,查看下面的配置类可以知道,这些属性存在默认值;
server:
port: 8082 # 端口号
tomcat: # Tomcat组件
uri-encoding: UTF-8 # URI编码
max-threads: 100 # 最大工作线程
min-spare-threads: 10 # 最小工作线程
2、属性配置类
在服务配置中,提供多种服务器的适配,像Tomcat、Jetty、Netty、Undertow,从策略上看,配置分为公共属性以及各种服务器的适配属性;
更多配置信息,可以参考完整的源码和注释说明;
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
private Integer port;
public static class Tomcat {
private Charset uriEncoding = StandardCharsets.UTF_8;
private int maxThreads = 200;
private int minSpareThreads = 10;
}
}
3、配置加载分析

- 基于配置的属性,定制化管理Tomcat服务的信息;
public class TomcatWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory> {
@Override
public void customize(ConfigurableTomcatWebServerFactory factory) {
ServerProperties properties = this.serverProperties;
ServerProperties.Tomcat tomcatProperties = properties.getTomcat();
PropertyMapper propertyMapper = PropertyMapper.get();
customizeStaticResources(factory);
}
}
- TomcatWeb服务工厂,这里在创建WebServer时,使用的是Tomcat,需要适当的了解一下Tomcat架构;
public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory
implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}
}
四、周期管理方法
1、控制类

- WebServer的简单接口,只声明端口获取,服务启动和停止相关方法;
public interface WebServer {
// 获取监听的端口
int getPort();
// 服务启动
void start() throws WebServerException;
// 服务停止
void stop() throws WebServerException;
}
- SpringBoot中,Tomcat服务核心控制类,通过TomcatServletWebServerFactory工厂类创建,对Tomcat生命周期的管理提供了一层包装;
public class TomcatWebServer implements WebServer {
private final Tomcat tomcat;
private final Map<Service, Connector[]> serviceConnectors = new HashMap<>();
}
- Apache组件中,轻量级Tomcat启动器,提供了Tomcat基础配置,比如默认的Port和HostName,以及生命周期管理的方法,TomcatWebServer类中调用的就是该API中的具体方法;
public class Tomcat {
protected Server server;
protected int port = 8080;
protected String hostname = "localhost";
// 初始化服务
public void init() throws LifecycleException {
getServer();
server.init();
}
// 启动服务
public void start() throws LifecycleException {
getServer();
server.start();
}
// 停止服务
public void stop() throws LifecycleException {
getServer();
server.stop();
}
}
2、核心方法
2.1 初始化,初始化时,调用Apache-Tomcat类中启动方法;
public class TomcatWebServer implements WebServer {
/**
* 初始化方法
*/
private void initialize() throws WebServerException {
// 控制台日志
logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
synchronized (this.monitor) {
// 调用Apache-Tomcat类中启动方法
this.tomcat.start();
}
}
}
2.2 启动,在初始化的方法中,调用的Tomcat启动方法,这里对状态进行校验并输出日志;
public class TomcatWebServer implements WebServer {
/**
* 启动方法
*/
public void start() throws WebServerException {
synchronized (this.monitor) {
if (this.started) {
return;
}
checkThatConnectorsHaveStarted();
// 启动状态的标识
this.started = true;
// 控制台日志
logger.info("Tomcat started on port(s): " + getPortsDescription(true) + " with context path '"
+ getContextPath() + "'");
}
}
}
2.3 停止,在组件生命周期的常规管理逻辑中,停止服务之后进行销毁动作的执行,其中自然涉及到多个状态标识的转换;
public class TomcatWebServer implements WebServer {
/**
* 停止方法
*/
public void stop() throws WebServerException {
synchronized (this.monitor) {
// 状态变化
boolean wasStarted = this.started;
this.started = false;
// Tomcat服务停止
stopTomcat();
this.tomcat.destroy();
}
}
}
五、参考源码
编程文档:
https://gitee.com/cicadasmile/butte-java-note
应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent
SpringBoot集成Tomcat服务的更多相关文章
- SpringBoot集成Socket服务后打包(war包)启动时如何启动Socket服务(web应用外部tomcat启动)
1.首先知道SpringBoot打包为jar和war包是不一样的(只讨论SpringBoot环境下web应用打包) 1.1.jar和war包的打开方式不一样,虽然都依赖java环境,但是j ...
- springboot集成邮件服务
一.前言 Spring Email 抽象的核心是 MailSender 接口,MailSender 的实现能够把 Email 发送给邮件服务器,由邮件服务器实现邮件发送的功能. Spring 自带了一 ...
- springboot集成dubbo服务报错No provider available for the service
检查了下发现是因为没有正确编写暴露服务的注解,需要注意下: @Service(interfaceClass = StudentService.) @Component public class Stu ...
- Springboot集成邮箱服务发送邮件
一.前言 Spring Email 抽象的核心是 MailSender 接口,MailSender 的实现能够把 Email 发送给邮件服务器,由邮件服务器实现邮件发送的功能. Spring 自带了一 ...
- springboot与thrift集成实现服务端和客户端
我们这里用一个简单的小功能来演示一下如何使用springboot集成thrift 这个功能是,判断hdfs路径存在. 1.先解决依赖 <dependencies> <dependen ...
- idea/eclipse下Maven工程集成web服务(tomcat、jetty)
idea/eclipse下Maven工程集成web服务 转载请注明出处:http://www.cnblogs.com/funnyzpc/p/8093554.html 应用服务器最常用的一般有这哥仨: ...
- 使用springboot集成腾讯云短信服务,解决配置文件读取乱码问题
springboot集成腾讯云短信服务: (1)导入依赖 <dependency> <groupId>org.springframework.boot</groupId& ...
- springboot集成mail实现邮件服务
1,新建mailconfig类,对邮件服务固定配置进行实体封装: import java.util.Properties; import org.springframework.beans.facto ...
- SpringBoot集成JWT 实现接口权限认证
JWT介绍 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的, 特别适用于分布式站点 ...
- springboot集成Spring Session
10.1 分布式集群环境下的集成(同域名.同项目) 10.1.1 创建SpringBoot的web支持项目07-springboot-session 创建项目 10.1.2 ...
随机推荐
- 我要涨知识——TypeScript 常见面试题(二)
又是一个年底来了,好大一批人可能又准备跑路了,最近回家待产,翻了翻掘金和 CSDN 发现好多大佬都有大厂 Offer ,看着看着我心动了! 话不多说,赶紧开干,给自己整了一个前端面试小助手--微信小程 ...
- Django基础笔记6(Django中间件)
Django自带的中间件 中间件执行流程 自定义中间件 Middle.py class Middle1(MiddlewareMixin): def process_request(self, requ ...
- python面向对象推导流程
举例:猫狗大战 # 1.例如我们要编写一个猫狗对战小游戏 # 首先我们要定义一个猫,和一只狗 cat1 = { 'name': '小白猫', 'type': '宠物猫', 'attack_val': ...
- 跳出foreach循环
直接return false没用,需要用throw来跳出foreach 1 try { 2 this.categoryList.forEach((item, index) => { 3 if ( ...
- 记一次InputStream流读取不完整留下的惨痛教训
前言 首先,问问大家下面这段流读取的代码是否存在问题呢? inputStream = .... try { // 根据inputStream的长度创建字节数组 byte[] arrayOfByte = ...
- 简易博客页面小项目 html css
项目预览 代码 html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- 【Spring专题】「开发指南」夯实实战基础功底之解读logback-spring.xml文件的详解实现
logback的maven配置 <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j- ...
- 详解JAVA线程问题诊断工具Thread Dump
摘要:Thread Dump是非常有用的诊断Java应用问题的工具. 本文分享自华为云社区<调试排错 - Java 线程分析之线程Dump分析>,作者:龙哥手记. Thread Dump是 ...
- 解决多次重连rabbitMQ失败
项目中有用到rabbitMQ,但由于防火墙原因只有在SIT环境下才能连上rabbitMQ,在本地是无法连上rabbitMQ的.如下: 为了不影响调试,临时解决方法为禁止rabbitMQ打印日志.在lo ...
- 图文并茂--微信小程序,获取用户地理位置信息,并调用腾讯地图API来获取用户具体位置
今天开始搞这个东西,下面是详细的记录 先看一下效果啦 1.小程序代码先获取用户基础位置信息 js data: { myLocation: 'GET LOCATION', }, openMap() { ...