通过@AutoConfiguration注解加载ServletWebServerFactoryAutoConfiguration配置类,该类通过@Import注解导入符合条件的内嵌servlet容器的配置(EmbeddedTomcat、EmbeddedJetty、EmbeddedUndertow),注册对应的servletwebserver的bean信息,spring boot在执行run方法过程中,会执行onRefresh方法,在该方法中会进行webServer容器创建。
@Override
protected void onRefresh() {
super.onRefresh();
try {
//执行创建webServer方法
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
createWebServer方法
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
//获取IOC容器中的servletWebServerFactory(如果存在多个容器的jar时会抛异常)
ServletWebServerFactory factory = getWebServerFactory();
//创建servletWebServer
this.webServer = factory.getWebServer(getSelfInitializer());
//注册webServerLifecycle,在容器启动完成后(执行finishRefresh)调用
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
//注册WebServerStartStopLifecycle,在IOC容器启动完成后,执行WebServer的start方法
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);
}
}
initPropertySources();
}
TomcatServletWebServerFactory的getWebServer方法
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
//创建tomcat
Tomcat tomcat = new Tomcat();
//设置tomcat参数
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
for (LifecycleListener listener : this.serverLifecycleListeners) {
tomcat.getServer().addLifecycleListener(listener);
}
//创建connector组件
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());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
//启动tomcat
return getTomcatWebServer(tomcat);
}
Spring IOC容器启动完成后,在执行finishRefresh时,会调用DefaultLifecycleProcessor的onRefresh方法,最终调用容器中所有的SmartLifecycle对象的start方法。因在创建servletWebServer时,向容器中注册了WebServerStartStopLifecycle对象,因此在执行startBeans方法时,将会调用WebServerStartStopLifecycle的start方法启动servlet容器中的需要启动的servlet。
private void startBeans(boolean autoStartupOnly) {
//获取IOC容器中所有的Lifecycle
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
if (group == null) {
//封装为group对象,避免多个Lifecycle的Phase相同被覆盖问题
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
if (!phases.isEmpty()) {
//对Phase进行升序排序
List<Integer> keys = new ArrayList<>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
//分组调用SmartLifecycle start方法
phases.get(key).start();
}
}
}