应用的老本越低,外部封装越简单;
一、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