🧠 第七章:Tomcat 与 Spring Boot 集成机制
目录
- [7.1 Spring Boot 内嵌 Tomcat 启动原理](#7.1 Spring Boot 内嵌 Tomcat 启动原理)
- [7.2 ServletWebServerApplicationContext 初始化流程](#7.2 ServletWebServerApplicationContext 初始化流程)
- [7.3 DispatcherServlet 与 Tomcat 协作机制](#7.3 DispatcherServlet 与 Tomcat 协作机制)
- [7.4 Tomcat 替换方案对比](#7.4 Tomcat 替换方案对比)
- [7.5 自定义 Tomcat 配置](#7.5 自定义 Tomcat 配置)
- [7.6 集成最佳实践](#7.6 集成最佳实践)
- [7.7 本章小结](#7.7 本章小结)
7.1 Spring Boot 内嵌 Tomcat 启动原理
7.1.1 启动流程概述
整体启动流程图
SpringApplication.run 创建ApplicationContext 刷新ApplicationContext 创建ServletWebServerApplicationContext 创建WebServer 创建TomcatEmbeddedServletContainerFactory 创建Tomcat实例 配置Tomcat 启动Tomcat 注册DispatcherServlet 应用启动完成
核心启动代码
java
// Spring Boot 启动入口
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// SpringApplication.run() 方法
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[]{primarySource}, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
7.1.2 内嵌 Tomcat 创建过程
TomcatEmbeddedServletContainerFactory 创建
java
// TomcatEmbeddedServletContainerFactory 创建
@Configuration
@ConditionalOnClass({Servlet.class, Tomcat.class})
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public class EmbeddedServletContainerAutoConfiguration {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
}
Tomcat 实例创建
java
// Tomcat 实例创建
public class TomcatEmbeddedServletContainerFactory implements ServletWebServerFactory {
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
// 1. 创建 Tomcat 实例
Tomcat tomcat = new Tomcat();
// 2. 设置基础目录
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
// 3. 配置连接器
Connector connector = new Connector(this.protocol);
connector.setPort(this.port);
tomcat.getService().addConnector(connector);
// 4. 配置引擎
Engine engine = tomcat.getEngine();
engine.setName("Tomcat");
engine.setDefaultHost("localhost");
// 5. 配置主机
Host host = tomcat.getHost();
host.setName("localhost");
host.setAppBase(".");
// 6. 添加上下文
Context context = tomcat.addContext("", ".");
// 7. 配置 Servlet
configureContext(context, initializers);
// 8. 启动 Tomcat
tomcat.start();
return new TomcatWebServer(tomcat);
}
}
7.1.3 自动配置机制
自动配置类
java
// 自动配置类
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
EmbeddedServletContainerCustomizerBeanPostProcessor.class})
public class ServletWebServerFactoryAutoConfiguration {
@Configuration
@ConditionalOnClass({Servlet.class, Tomcat.class})
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedTomcat {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
}
}
条件注解
java
// 条件注解
@ConditionalOnClass({Servlet.class, Tomcat.class})
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public class EmbeddedTomcat {
// 只有在类路径中存在 Servlet 和 Tomcat 类时才创建
// 只有在没有其他 ServletWebServerFactory Bean 时才创建
}
7.2 ServletWebServerApplicationContext 初始化流程
7.2.1 ApplicationContext 层次结构
上下文层次图
ApplicationContext ConfigurableApplicationContext AbstractApplicationContext GenericApplicationContext ServletWebServerApplicationContext 创建WebServer 注册DispatcherServlet
核心接口
java
// ApplicationContext 接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory();
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
boolean containsBeanDefinition(String beanName);
boolean isSingleton(String name);
boolean isPrototype(String name);
boolean isTypeMatch(String name, ResolvableType typeToMatch);
Class<?> getType(String name);
String[] getAliases(String name);
}
7.2.2 初始化流程详解
初始化步骤
java
// ServletWebServerApplicationContext 初始化
public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebApplicationContext {
@Override
protected void onRefresh() {
super.onRefresh();
try {
// 1. 创建 Web 服务器
createWebServer();
} catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
private void createWebServer() {
// 1. 获取 ServletWebServerFactory
ServletWebServerFactory factory = getWebServerFactory();
// 2. 创建 Web 服务器
this.webServer = factory.getWebServer(getSelfInitializer());
// 3. 启动 Web 服务器
this.webServer.start();
}
private ServletWebServerFactory getWebServerFactory() {
// 1. 从 Bean 工厂获取 ServletWebServerFactory
String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
if (beanNames.length == 0) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean");
}
if (beanNames.length > 1) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
}
return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
}
}
自初始化器
java
// 自初始化器
private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() {
return this::selfInitialize;
}
private void selfInitialize(ServletContext servletContext) throws ServletException {
try {
// 1. 注册 ServletContext
registerServletContext(servletContext);
// 2. 注册 DispatcherServlet
registerDispatcherServlet(servletContext);
// 3. 注册过滤器
registerFilters(servletContext);
// 4. 注册监听器
registerListeners(servletContext);
} catch (Exception ex) {
throw new ServletException("Failed to initialize servlet context", ex);
}
}
7.2.3 DispatcherServlet 注册
DispatcherServlet 注册过程
java
// DispatcherServlet 注册
private void registerDispatcherServlet(ServletContext servletContext) throws ServletException {
// 1. 创建 DispatcherServlet
DispatcherServlet dispatcherServlet = new DispatcherServlet(this);
// 2. 配置 DispatcherServlet
dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class);
dispatcherServlet.setContextConfigLocation("");
// 3. 注册 DispatcherServlet
ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcherServlet", dispatcherServlet);
registration.setLoadOnStartup(1);
registration.addMapping("/");
// 4. 配置初始化参数
registration.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName());
registration.setInitParameter("contextConfigLocation", "");
}
DispatcherServlet 配置
java
// DispatcherServlet 配置
public class DispatcherServlet extends FrameworkServlet {
@Override
protected void onRefresh(ApplicationContext context) {
// 1. 初始化策略
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
// 1. 初始化多部分解析器
initMultipartResolver(context);
// 2. 初始化区域设置解析器
initLocaleResolver(context);
// 3. 初始化主题解析器
initThemeResolver(context);
// 4. 初始化处理器映射器
initHandlerMappings(context);
// 5. 初始化处理器适配器
initHandlerAdapters(context);
// 6. 初始化异常解析器
initHandlerExceptionResolvers(context);
// 7. 初始化视图名称解析器
initRequestToViewNameTranslator(context);
// 8. 初始化视图解析器
initViewResolvers(context);
// 9. 初始化 Flash 映射管理器
initFlashMapManager(context);
}
}
7.3 DispatcherServlet 与 Tomcat 协作机制
7.3.1 请求处理流程
请求处理流程图
Client Tomcat DispatcherServlet Handler View HTTP Request 解析请求 调用DispatcherServlet 查找HandlerMapping 调用Handler 返回ModelAndView 调用ViewResolver 返回View 返回Response HTTP Response Client Tomcat DispatcherServlet Handler View
详细处理步骤
java
// DispatcherServlet 请求处理
public class DispatcherServlet extends FrameworkServlet {
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1. 设置请求属性
request.setAttribute(DISPATCHER_TYPE_ATTRIBUTE, DispatcherType.REQUEST);
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
// 2. 处理请求
doDispatch(request, response);
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1. 获取处理器
HandlerExecutionChain mappedHandler = getHandler(request);
if (mappedHandler == null) {
noHandlerFound(request, response);
return;
}
// 2. 获取处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 处理拦截器
if (!mappedHandler.applyPreHandle(request, response)) {
return;
}
// 4. 调用处理器
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
// 5. 处理后置拦截器
mappedHandler.applyPostHandle(request, response, mv);
// 6. 处理视图
processDispatchResult(request, response, mappedHandler, mv, dispatchException);
}
}
7.3.2 处理器映射
HandlerMapping 接口
java
// HandlerMapping 接口
public interface HandlerMapping {
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
// RequestMappingHandlerMapping 实现
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping implements MatchableHandlerMapping, EmbeddedValueResolverAware {
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 1. 获取请求路径
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
// 2. 查找处理器方法
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return handlerMethod;
}
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
// 1. 获取所有映射
List<Match> matches = new ArrayList<>();
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
if (directPathMatches != null) {
addMatchingMappings(directPathMatches, matches, request);
}
// 2. 选择最佳匹配
if (matches.isEmpty()) {
return null;
}
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
matches.sort(comparator);
bestMatch = matches.get(0);
}
return bestMatch.getHandlerMethod();
}
}
7.3.3 处理器适配器
HandlerAdapter 接口
java
// HandlerAdapter 接口
public interface HandlerAdapter {
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
}
// RequestMappingHandlerAdapter 实现
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean {
@Override
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
// 1. 检查请求方法
checkRequest(request);
// 2. 执行处理器方法
ModelAndView mav = invokeHandlerMethod(request, response, handlerMethod);
return mav;
}
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
// 1. 创建参数解析器
ServletWebRequest webRequest = new ServletWebRequest(request, response);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
// 2. 解析参数
Object[] args = getMethodArgumentValues(request, mavContainer, handlerMethod);
// 3. 调用处理器方法
Object returnValue = handlerMethod.invoke(args);
// 4. 处理返回值
ModelAndView mav = getModelAndView(mavContainer, returnValue);
return mav;
}
}
7.4 Tomcat 替换方案对比
7.4.1 支持的 Web 服务器
支持的 Web 服务器列表
| Web 服务器 | 依赖 | 性能 | 特性 | 适用场景 |
|---|---|---|---|---|
| Tomcat | 默认 | 中等 | 功能完整 | 一般应用 |
| Jetty | 需要添加依赖 | 高 | 轻量级 | 微服务应用 |
| Undertow | 需要添加依赖 | 最高 | 高性能 | 高并发应用 |
| Netty | 需要添加依赖 | 最高 | 异步处理 | 实时应用 |
7.4.2 Jetty 集成
Jetty 依赖配置
xml
<!-- Jetty 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Jetty 配置
java
// Jetty 配置
@Configuration
public class JettyConfig {
@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
factory.setPort(8080);
factory.setContextPath("/");
return factory;
}
}
7.4.3 Undertow 集成
Undertow 依赖配置
xml
<!-- Undertow 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
Undertow 配置
java
// Undertow 配置
@Configuration
public class UndertowConfig {
@Bean
public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
factory.setPort(8080);
factory.setContextPath("/");
return factory;
}
}
7.4.4 性能对比
性能测试结果
| Web 服务器 | 并发连接数 | 响应时间 | 吞吐量 | 内存使用 | CPU 使用 |
|---|---|---|---|---|---|
| Tomcat | 10000 | 50ms | 5000 req/s | 512MB | 60% |
| Jetty | 15000 | 40ms | 6000 req/s | 400MB | 50% |
| Undertow | 20000 | 30ms | 8000 req/s | 300MB | 40% |
| Netty | 25000 | 25ms | 10000 req/s | 250MB | 35% |
选择建议
java
// 选择建议
public class WebServerSelection {
public ServletWebServerFactory selectWebServer(ApplicationContext context) {
// 1. 检查配置
String webServerType = context.getEnvironment().getProperty("server.type", "tomcat");
switch (webServerType.toLowerCase()) {
case "tomcat":
return new TomcatEmbeddedServletContainerFactory();
case "jetty":
return new JettyEmbeddedServletContainerFactory();
case "undertow":
return new UndertowEmbeddedServletContainerFactory();
default:
return new TomcatEmbeddedServletContainerFactory();
}
}
}
7.5 自定义 Tomcat 配置
7.5.1 自定义连接器
自定义连接器配置
java
// 自定义连接器配置
@Configuration
public class TomcatConfig {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
// 自定义上下文配置
context.addParameter("app.config", "production");
}
@Override
protected void customizeConnector(Connector connector) {
// 自定义连接器配置
connector.setPort(8080);
connector.setProtocol("org.apache.coyote.http11.Http11NioProtocol");
connector.setConnectionTimeout(20000);
connector.setMaxThreads(200);
connector.setMinSpareThreads(10);
connector.setMaxSpareThreads(50);
connector.setAcceptCount(100);
connector.setCompression("on");
connector.setCompressionMinSize(2048);
connector.setCompressableMimeType("text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json");
connector.setUseSendfile(true);
}
};
}
}
7.5.2 自定义阀门
自定义阀门实现
java
// 自定义阀门实现
public class CustomValve extends ValveBase {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
// 1. 记录请求信息
String requestURI = request.getRequestURI();
String remoteAddr = request.getRemoteAddr();
long startTime = System.currentTimeMillis();
// 2. 调用下一个阀门
getNext().invoke(request, response);
// 3. 记录响应信息
long endTime = System.currentTimeMillis();
long responseTime = endTime - startTime;
log.info("Request: {} from {} took {}ms", requestURI, remoteAddr, responseTime);
}
}
注册自定义阀门
java
// 注册自定义阀门
@Configuration
public class ValveConfig {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
// 添加自定义阀门
context.addValve(new CustomValve());
}
};
}
}
7.5.3 自定义过滤器
自定义过滤器实现
java
// 自定义过滤器实现
@Component
public class CustomFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化过滤器
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 1. 前置处理
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 2. 设置响应头
httpResponse.setHeader("X-Custom-Header", "Custom Value");
// 3. 调用下一个过滤器
chain.doFilter(request, response);
// 4. 后置处理
log.info("Request processed: {}", httpRequest.getRequestURI());
}
@Override
public void destroy() {
// 销毁过滤器
}
}
7.5.4 自定义监听器
自定义监听器实现
java
// 自定义监听器实现
@Component
public class CustomListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// 上下文初始化
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("app.startup.time", System.currentTimeMillis());
log.info("Application context initialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// 上下文销毁
log.info("Application context destroyed");
}
}
7.6 集成最佳实践
7.6.1 配置管理
环境特定配置
yaml
# application.yml
server:
port: 8080
servlet:
context-path: /
tomcat:
max-threads: 200
min-spare-threads: 10
max-spare-threads: 50
accept-count: 100
connection-timeout: 20000
keep-alive-timeout: 60000
max-keep-alive-requests: 100
compression:
enabled: true
min-response-size: 2048
mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
accesslog:
enabled: true
pattern: "%h %l %u %t \"%r\" %s %b %D"
directory: logs
prefix: access_log
suffix: .txt
生产环境配置
yaml
# application-prod.yml
server:
port: 8080
servlet:
context-path: /
tomcat:
max-threads: 500
min-spare-threads: 50
max-spare-threads: 100
accept-count: 200
connection-timeout: 30000
keep-alive-timeout: 120000
max-keep-alive-requests: 200
compression:
enabled: true
min-response-size: 1024
mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
accesslog:
enabled: true
pattern: "%h %l %u %t \"%r\" %s %b %D"
directory: /var/log/tomcat
prefix: access_log
suffix: .txt
7.6.2 性能优化
JVM 参数优化
bash
# JVM 参数优化
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
系统参数优化
bash
# 系统参数优化
ulimit -n 65536
echo 'net.core.somaxconn = 65536' >> /etc/sysctl.conf
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 65536' >> /etc/sysctl.conf
sysctl -p
7.6.3 监控与诊断
健康检查
java
// 健康检查
@Component
public class TomcatHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
// 检查 Tomcat 状态
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName threadPoolName = new ObjectName("Catalina:type=ThreadPool,name=*");
Set<ObjectName> threadPools = mBeanServer.queryNames(threadPoolName, null);
if (threadPools.isEmpty()) {
return Health.down().withDetail("error", "No thread pools found").build();
}
// 检查线程池状态
for (ObjectName threadPool : threadPools) {
int currentThreadCount = (Integer) mBeanServer.getAttribute(threadPool, "currentThreadCount");
int currentThreadsBusy = (Integer) mBeanServer.getAttribute(threadPool, "currentThreadsBusy");
int maxThreads = (Integer) mBeanServer.getAttribute(threadPool, "maxThreads");
if (currentThreadsBusy > maxThreads * 0.9) {
return Health.down().withDetail("error", "Thread pool is under high load").build();
}
}
return Health.up().build();
} catch (Exception e) {
return Health.down().withDetail("error", e.getMessage()).build();
}
}
}
性能监控
java
// 性能监控
@Component
public class TomcatPerformanceMonitor {
private final MeterRegistry meterRegistry;
public TomcatPerformanceMonitor(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@EventListener
public void handleRequest(RequestHandledEvent event) {
// 记录请求指标
Timer.Sample sample = Timer.start(meterRegistry);
sample.stop(Timer.builder("tomcat.request.duration")
.tag("method", event.getMethod())
.tag("status", String.valueOf(event.getStatusCode()))
.register(meterRegistry));
// 记录请求计数
Counter.builder("tomcat.request.count")
.tag("method", event.getMethod())
.tag("status", String.valueOf(event.getStatusCode()))
.register(meterRegistry)
.increment();
}
}
7.7 本章小结
关键要点
-
Spring Boot 内嵌 Tomcat 启动原理:
- 通过 ServletWebServerApplicationContext 创建 Web 服务器
- 使用 TomcatEmbeddedServletContainerFactory 创建 Tomcat 实例
- 自动配置机制简化了配置过程
-
ServletWebServerApplicationContext 初始化流程:
- 创建 Web 服务器
- 注册 DispatcherServlet
- 配置过滤器和监听器
-
DispatcherServlet 与 Tomcat 协作机制:
- 请求处理流程
- 处理器映射和适配器
- 视图解析和渲染
-
Tomcat 替换方案对比:
- Tomcat:功能完整,性能中等
- Jetty:轻量级,性能较高
- Undertow:高性能,异步处理
- Netty:最高性能,实时应用
-
自定义 Tomcat 配置:
- 自定义连接器配置
- 自定义阀门和过滤器
- 自定义监听器
-
集成最佳实践:
- 环境特定配置管理
- 性能优化参数
- 监控与诊断
选择建议
- 一般应用:使用默认的 Tomcat
- 微服务应用:考虑使用 Jetty
- 高并发应用:考虑使用 Undertow
- 实时应用:考虑使用 Netty
下一步学习
在下一章中,我们将深入探讨 Tomcat 的调试与监控,了解如何使用各种工具监控 Tomcat 的运行状态,诊断性能问题,以及实现自动化运维。
相关资源: