Starter for using Tomcat as the embedded servlet container, providing default servlet container functionality for Spring Boot web applications
—
Automatic configuration classes that set up Tomcat components based on classpath detection and application properties. Spring Boot's auto-configuration system provides convention-over-configuration setup while allowing extensive customization through properties and custom beans.
Main auto-configuration class for servlet web servers, including Tomcat support. Conditionally creates web server factory beans and customizers.
/**
* Auto-configuration for servlet web server factories
*/
@AutoConfiguration
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = WebApplicationType.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
/** Creates servlet web server factory customizer */
@Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(
ServerProperties serverProperties,
ObjectProvider<WebListenerRegistrar> webListenerRegistrars,
ObjectProvider<CookieSameSiteSupplier> cookieSameSiteSuppliers);
/** Creates Tomcat servlet web server factory customizer */
@Bean
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
ServerProperties serverProperties);
/** Creates forwarded header filter when configured */
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "server.forward-headers-strategy", havingValue = "framework")
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter();
}Configuration class specifically for embedded Tomcat web server factory creation.
/**
* Configuration for embedded Tomcat servlet web server factory
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class,
search = SearchStrategy.CURRENT)
static class EmbeddedTomcat {
/** Creates Tomcat servlet web server factory bean */
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
// Apply all discovered customizers
factory.getTomcatConnectorCustomizers()
.addAll(connectorCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatContextCustomizers()
.addAll(contextCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatProtocolHandlerCustomizers()
.addAll(protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));
return factory;
}
}Applies ServerProperties configuration to Tomcat servlet web server factories.
/**
* Customizer that applies ServerProperties to Tomcat servlet web server factories
*/
public class TomcatServletWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered {
/** Constructor with server properties */
public TomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties);
/** Applies Tomcat-specific configuration from properties */
@Override
public void customize(TomcatServletWebServerFactory factory) {
ServerProperties.Tomcat tomcatProperties = serverProperties.getTomcat();
// Apply TLD skip patterns
if (!tomcatProperties.getAdditionalTldSkipPatterns().isEmpty()) {
factory.addTldSkipPatterns(tomcatProperties.getAdditionalTldSkipPatterns()
.toArray(new String[0]));
}
// Apply context root redirect setting
if (tomcatProperties.getRedirectContextRoot() != null) {
customizeRedirectContextRoot(factory, tomcatProperties.getRedirectContextRoot());
}
// Apply relative redirects setting
customizeUseRelativeRedirects(factory, tomcatProperties.getUseRelativeRedirects());
// Apply MBean registry setting
customizeDisableMBeanRegistry(factory, tomcatProperties.getMbeanregistry());
}
/** Returns execution order for this customizer */
@Override
public int getOrder();
}Applies common Tomcat configuration for both servlet and reactive web server factories.
/**
* Customizer that applies common Tomcat configuration to web server factories
*/
public class TomcatWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>, Ordered {
/** Constructor with server properties */
public TomcatWebServerFactoryCustomizer(ServerProperties serverProperties);
/** Applies common Tomcat configuration from properties */
@Override
public void customize(ConfigurableTomcatWebServerFactory factory) {
ServerProperties.Tomcat tomcatProperties = serverProperties.getTomcat();
// Base directory configuration
if (tomcatProperties.getBasedir() != null) {
factory.setBaseDirectory(tomcatProperties.getBasedir());
}
// Background processor delay
if (tomcatProperties.getBackgroundProcessorDelay() != null) {
factory.setBackgroundProcessorDelay(
(int) tomcatProperties.getBackgroundProcessorDelay().getSeconds());
}
// URI encoding
if (tomcatProperties.getUriEncoding() != null) {
factory.setUriEncoding(tomcatProperties.getUriEncoding());
}
// Apply connector customizations
customizeConnector(factory, tomcatProperties);
// Apply static resource settings
customizeStaticResources(factory, tomcatProperties.getResource());
// Apply remote IP configuration
customizeRemoteIpValve(factory, tomcatProperties.getRemoteip());
}
/** Returns execution order for this customizer */
@Override
public int getOrder();
}Auto-configuration for reactive web servers, including Tomcat reactive support.
/**
* Auto-configuration for reactive web server factories
*/
@AutoConfiguration
@ConditionalOnClass(HttpHandler.class)
@ConditionalOnWebApplication(type = WebApplicationType.REACTIVE)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ReactiveWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
ReactiveWebServerFactoryConfiguration.EmbeddedTomcat.class,
ReactiveWebServerFactoryConfiguration.EmbeddedJetty.class,
ReactiveWebServerFactoryConfiguration.EmbeddedUndertow.class,
ReactiveWebServerFactoryConfiguration.EmbeddedNetty.class })
public class ReactiveWebServerFactoryAutoConfiguration {
/** Creates reactive web server factory customizer */
@Bean
public ReactiveWebServerFactoryCustomizer reactiveWebServerFactoryCustomizer(
ServerProperties serverProperties);
}Configuration class for embedded Tomcat reactive web server factory.
/**
* Configuration for embedded Tomcat reactive web server factory
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Tomcat.class })
@ConditionalOnMissingBean(value = ReactiveWebServerFactory.class,
search = SearchStrategy.CURRENT)
static class EmbeddedTomcat {
/** Creates Tomcat reactive web server factory bean */
@Bean
TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory(
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory();
// Apply customizers
factory.getTomcatConnectorCustomizers()
.addAll(connectorCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatContextCustomizers()
.addAll(contextCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatProtocolHandlerCustomizers()
.addAll(protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));
return factory;
}
}Applies configuration to Tomcat reactive web server factories.
/**
* Customizer for Tomcat reactive web server factories
*/
public class TomcatReactiveWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<TomcatReactiveWebServerFactory>, Ordered {
/** Constructor with server properties */
public TomcatReactiveWebServerFactoryCustomizer(ServerProperties serverProperties);
/** Applies Tomcat reactive-specific configuration */
@Override
public void customize(TomcatReactiveWebServerFactory factory);
/** Returns execution order for this customizer */
@Override
public int getOrder();
}Customizes Tomcat for WebSocket support in servlet environments.
/**
* Customizer for Tomcat WebSocket support in servlet environments
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Tomcat.class, WsSci.class })
static class TomcatWebSocketConfiguration {
/** Creates WebSocket servlet web server customizer */
@Bean
@ConditionalOnMissingBean(name = "tomcatWebSocketServletWebServerCustomizer")
TomcatWebSocketServletWebServerCustomizer tomcatWebSocketServletWebServerCustomizer() {
return new TomcatWebSocketServletWebServerCustomizer();
}
}Customizes Tomcat for WebSocket support in reactive environments.
/**
* Customizer for Tomcat WebSocket support in reactive environments
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Tomcat.class, WsSci.class })
static class TomcatWebSocketReactiveConfiguration {
/** Creates WebSocket reactive web server customizer */
@Bean
@ConditionalOnMissingBean(name = "tomcatWebSocketReactiveWebServerCustomizer")
TomcatWebSocketReactiveWebServerCustomizer tomcatWebSocketReactiveWebServerCustomizer() {
return new TomcatWebSocketReactiveWebServerCustomizer();
}
}Auto-configuration for Tomcat metrics collection through Micrometer.
/**
* Auto-configuration for Tomcat metrics collection
*/
@AutoConfiguration(after = { MetricsAutoConfiguration.class,
CompositeMeterRegistryAutoConfiguration.class })
@ConditionalOnClass({ Tomcat.class, MeterRegistry.class })
@ConditionalOnBean(MeterRegistry.class)
@ConditionalOnProperty(value = "management.metrics.web.server.request.autotime.enabled",
matchIfMissing = true)
@EnableConfigurationProperties(MetricsProperties.class)
public class TomcatMetricsAutoConfiguration {
/** Creates Tomcat metrics binder */
@Bean
@ConditionalOnMissingBean
public TomcatMetricsBinder tomcatMetricsBinder(MeterRegistry meterRegistry) {
return new TomcatMetricsBinder(meterRegistry);
}
/** Creates Tomcat metrics web server factory customizer */
@Bean
@ConditionalOnMissingBean
public TomcatMetricsWebServerFactoryCustomizer tomcatMetricsCustomizer(
MeterRegistry meterRegistry, MetricsProperties metricsProperties) {
return new TomcatMetricsWebServerFactoryCustomizer(meterRegistry, metricsProperties);
}
}Auto-configuration uses Spring Boot's conditional annotations to ensure proper component setup:
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
// Only activate when Tomcat classes are available
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
// Check for specific Tomcat class by name@ConditionalOnMissingBean(value = ServletWebServerFactory.class)
// Only create if no other web server factory exists
@ConditionalOnBean(MeterRegistry.class)
// Only create if MeterRegistry bean exists@ConditionalOnProperty(value = "server.forward-headers-strategy",
havingValue = "framework")
// Only activate when specific property value is set
@ConditionalOnProperty(value = "management.metrics.web.server.request.autotime.enabled",
matchIfMissing = true)
// Activate by default unless explicitly disabled@ConditionalOnWebApplication(type = WebApplicationType.SERVLET)
// Only for servlet web applications
@ConditionalOnWebApplication(type = WebApplicationType.REACTIVE)
// Only for reactive web applicationsAuto-configuration components are processed in a specific order:
ServletWebServerFactoryAutoConfiguration or ReactiveWebServerFactoryAutoConfigurationThis ordering ensures that user customizations can override framework defaults while maintaining proper initialization sequence.
Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-tomcat