自动装配加载 ServletWebServerFactoryAutoConfiguration
在自动装配的时候,会加载spring.factories,并且添加到IOC容器中。这里包含web自动配置类ServletWebServerFactoryAutoConfiguration
,其中本类中注入三个bean,分别是EmbeddedTomcat\EmbeddedJetty\EmbeddedUndertow, 以及可以添加自定义BD的BeanPostProcessorsRegistrar
@Configuration(proxyBeanMethods = false) // 配置类
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) // 自动装配的顺序
@ConditionalOnClass(ServletRequest.class) // 引入Servlet的依赖才生效
@ConditionalOnWebApplication(type = Type.SERVLET) // 当Web容器是Servlet才生效
@EnableConfigurationProperties(ServerProperties.class) // 关联对应的属性配置类
// 通过 @Import注解引入一些Web容器
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,// 引入一些对应的容器的类对象
ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
/**
* 这里注入了一个ServletWebServer的定制工厂
* @param serverProperties
* @return
*/
@Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
return new ServletWebServerFactoryCustomizer(serverProperties);
}
@Bean
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
ServerProperties serverProperties) {
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
}
/**
* Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
* {@link ImportBeanDefinitionRegistrar} for early registration.
*/
public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
private ConfigurableListableBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
if (this.beanFactory == null) {
return;
}
// 向容器中注册了一个后置处理器
registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor",
WebServerFactoryCustomizerBeanPostProcessor.class);
registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor",
ErrorPageRegistrarBeanPostProcessor.class);
}
private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name, Class<?> beanClass) {
if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
beanDefinition.setSynthetic(true);
registry.registerBeanDefinition(name, beanDefinition);
}
}
}
}
初始化和启动 tomcat
在ioc容器刷新时候,进行自定义拓展,实现tomcat的创建。
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start reactive web server", ex);
}
}
// tomcat执行
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = getWebServerFactory();// 获取WebServer的工厂对象
this.webServer = factory.getWebServer(getSelfInitializer()); // 获取具体的WebServer
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
// 获取tomcat工厂 调用getBean会进行初始化、实例化操作
protected ServletWebServerFactory getWebServerFactory() {
// Use bean names so that we don't consider the hierarchy
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);
}
创建tomcat对象
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
Tomcat tomcat = new Tomcat();// 创建Tomcat容器,并且配置连接器,引擎等属性
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);// 创建连接器
connector.setThrowOnFailure(true);
// 给service添加connector
tomcat.getService().addConnector(connector);
// 定制自己的连接器
customizeConnector(connector);
// 设置到tomcat中
tomcat.setConnector(connector);
// 自动部署 false
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine()); // 配置Engine
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);// Service关联Connector
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat); // 获取TomcatWebServer
}
public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
initialize(); // 非常重要的初始化方法 ⭐️
}
// 启动Tomcat通过发布事件触发一些Listener的初始化 也只是完成tomcat的初始化工作
this.tomcat.start();
// 启动tomcat
protected void finishRefresh() {
super.finishRefresh();
WebServer webServer = startWebServer();
if (webServer != null) {
publishEvent(new ServletWebServerInitializedEvent(webServer, this));
}
}