又是美好的一天呀~
个人博客地址: huanghong.top
本文预估阅读时长为15分钟左右~
org\springframework\boot\spring-boot-autoconfigure\2.6.6\spring-boot-autoconfigure-2.6.6.jar!\META-INF\spring.factories
//ServletWebServerFactoryConfiguration.EmbeddedTomcat.class
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
static class EmbeddedTomcat {
//构建TomcatServletWebServerFactory注入进Spring容器
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
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;
}
}
//org.springframework.context.support.AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
...
// Initialize other special beans in specific context subclasses.
//用于子类扩展
onRefresh();
...
}
}
//org.springframework.context.support.AbstractApplicationContext#onRefresh
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
//org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#onRefresh
protected void onRefresh() {
super.onRefresh();
try {
//创建并启动web服务器
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
//org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#createWebServer
private void createWebServer() {
//webServer、servletContext均为null
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
//获取web服务器工厂
ServletWebServerFactory factory = getWebServerFactory();
createWebServer.tag("factory", factory.getClass().toString());
//获取web服务器
this.webServer = factory.getWebServer(getSelfInitializer());
createWebServer.end();
//向Spring容器注册webServerGracefulShutdown Bean对象
//阻止处理新请求,并在尝试结束时调用给定的callback方法
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
//向Spring容器注册webServerStartStop Bean对象
//启动关闭server
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
//初始化servletContextInitParams,servletConfigInitParams web服务器属性资源
initPropertySources();
}
//org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#getWebServerFactory
protected ServletWebServerFactory getWebServerFactory() {
// Use bean names so that we don't consider the hierarchy
String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
//ServletWebServerFactory为空抛出异常
if (beanNames.length == 0) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
+ "ServletWebServerFactory bean.");
}
//ServletWebServerFactory实例个数大于1抛出异常
if (beanNames.length > 1) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
}
//只能构建一个ServletWebServerFactory
return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
}
//org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServer
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
//构建tomcat对象
Tomcat tomcat = new Tomcat();
//设置根路径
//C:\Users\Huang\AppData\Local\Temp\tomcat.端口.5924126900833427784
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
//设置生命周期监听器
for (LifecycleListener listener : this.serverLifecycleListeners) {
tomcat.getServer().addLifecycleListener(listener);
}
//构建连接器 赋值默认通讯协议org.apache.coyote.http11.Http11NioProtocol
Connector connector = new Connector(this.protocol);
//异常重新抛出
connector.setThrowOnFailure(true);
//添加连接器
tomcat.getService().addConnector(connector);
//根据扩展配置定制connector
customizeConnector(connector);
//设置连接器
tomcat.setConnector(connector);
//非自动部署
tomcat.getHost().setAutoDeploy(false);
//配置engine StandardEngine[Tomcat]
configureEngine(tomcat.getEngine());
//添加额外的tomcat连接器
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
//准备上下文
prepareContext(tomcat.getHost(), initializers);
//获取tomcat web服务器
return getTomcatWebServer(tomcat);
}
//org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#customizeConnector
protected void customizeConnector(Connector connector) {
//获取并设置端口号 默认8080
int port = Math.max(getPort(), 0);
connector.setPort(port);
if (StringUtils.hasText(getServerHeader())) {
connector.setProperty("server", getServerHeader());
}
//设置协议address
if (connector.getProtocolHandler() instanceof AbstractProtocol) {
customizeProtocol((AbstractProtocol<?>) connector.getProtocolHandler());
}
//执行protocolHandler自定义扩展
invokeProtocolHandlerCustomizers(connector.getProtocolHandler());
//编码设置 默认StandardCharsets.UTF_8
if (getUriEncoding() != null) {
connector.setURIEncoding(getUriEncoding().name());
}
//如果ApplicationContext启动缓慢,不要过早地绑定到套接字
connector.setProperty("bindOnInit", "false");
//http2协议设置
if (getHttp2() != null && getHttp2().isEnabled()) {
connector.addUpgradeProtocol(new Http2Protocol());
}
//ssl设置
if (getSsl() != null && getSsl().isEnabled()) {
customizeSsl(connector);
}
//执行压缩连接器自定义扩展
TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer(getCompression());
compression.customize(connector);
//执行TomcatConnectorCustomizer自定义扩展
for (TomcatConnectorCustomizer customizer : this.tomcatConnectorCustomizers) {
customizer.customize(connector);
}
}
//org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getTomcatWebServer
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
}
//org.springframework.boot.web.embedded.tomcat.TomcatWebServer#TomcatWebServer(org.apache.catalina.startup.Tomcat, boolean, org.springframework.boot.web.server.Shutdown)
public TomcatWebServer(Tomcat tomcat, boolean autoStart, Shutdown shutdown) {
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
//自动启动
this.autoStart = autoStart;
//优雅关闭
this.gracefulShutdown = (shutdown == Shutdown.GRACEFUL) ? new GracefulShutdown(tomcat) : null;
//初始化
initialize();
}
//org.springframework.boot.web.embedded.tomcat.TomcatWebServer#initialize
private void initialize() throws WebServerException {
logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
synchronized (this.monitor) {
try {
addInstanceIdToEngineName();
//获取上下文对象
Context context = findContext();
//添加监听器
context.addLifecycleListener((event) -> {
if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
// Remove service connectors so that protocol binding doesn't
// happen when the service is started.
removeServiceConnectors();
}
});
//启动tomcat
this.tomcat.start();
// 可以直接在主线程中重新抛出失败异常
rethrowDeferredStartupExceptions();
try {
ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
}
catch (NamingException ex) {
// Naming is not enabled. Continue
}
//与Jetty不同,所有Tomcat线程都是守护线程, 我们创建一个阻塞的非守护进程来阻止立即关机
startDaemonAwaitThread();
}
catch (Exception ex) {
stopSilently();
destroySilently();
throw new WebServerException("Unable to start embedded Tomcat", ex);
}
}
}
//org.springframework.boot.web.embedded.tomcat.TomcatWebServer#startDaemonAwaitThread
private void startDaemonAwaitThread() {
Thread awaitThread = new Thread("container-" + (containerCounter.get())) {
@Override
public void run() {
TomcatWebServer.this.tomcat.getServer().await();
}
};
awaitThread.setContextClassLoader(getClass().getClassLoader());
//设置为用户线程
awaitThread.setDaemon(false);
awaitThread.start();
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<version>2.6.6version>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jettyartifactId>
<version>2.6.6version>
dependency>
感谢阅读完本篇文章!!!
个人博客地址: huanghong.top