1、进入org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration
@Configuration
class ServletWebServerFactoryConfiguration {
@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
//判断当前是否引入了Tomcat依赖
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
//判断当前容器没有嵌入式的servlet容器工厂来创建嵌入式的servlet
public static class EmbeddedTomcat {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
}
进到ServletWebServerFactory类中
public interface ServletWebServerFactory {
//获取嵌入式的servlet
WebServer getWebServer(ServletContextInitializer... initializers);
}
切换容器的时候需要先移除,在引用
以tomcat为例,
ServletWebServerFactoryConfiguration类中
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({Servlet.class, Tomcat.class, UpgradeProtocol.class})
@ConditionalOnMissingBean(
value = {ServletWebServerFactory.class},
search = SearchStrategy.CURRENT
)
public static class EmbeddedTomcat {
public EmbeddedTomcat() {
}
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers, ObjectProvider<TomcatContextCustomizer> contextCustomizers, ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.getTomcatConnectorCustomizers().addAll((Collection)connectorCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatContextCustomizers().addAll((Collection)contextCustomizers.orderedStream().collect(Collectors.toList()));
factory.getTomcatProtocolHandlerCustomizers().addAll((Collection)protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));
return factory;
}
}
进入到TomcatServletWebServerFactory类
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
//创建一个tomcat
Tomcat tomcat = new Tomcat();
//配置tomcat的基本容器
File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
this.customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
this.configureEngine(tomcat.getEngine());
Iterator var5 = this.additionalTomcatConnectors.iterator();
while(var5.hasNext()) {
Connector additionalConnector = (Connector)var5.next();
tomcat.getService().addConnector(additionalConnector);
}
this.prepareContext(tomcat.getHost(), initializers);
//将配置好的tomcat传入进去,并且启动tomcat服务器
return this.getTomcatWebServer(tomcat);
}
进入getTomcatWebServer方法
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
return new TomcatWebServer(tomcat, this.getPort() >= 0);
}
public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
this.monitor = new Object();
this.serviceConnectors = new HashMap();
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
this.initialize();
}
private void initialize() throws WebServerException {
logger.info("Tomcat initialized with port(s): " + this.getPortsDescription(false));
synchronized(this.monitor) {
try {
this.addInstanceIdToEngineName();
Context context = this.findContext();
context.addLifecycleListener((event) -> {
if (context.equals(event.getSource()) && "start".equals(event.getType())) {
this.removeServiceConnectors();
}
});
this.tomcat.start();
this.rethrowDeferredStartupExceptions();
try {
ContextBindings.bindClassLoader(context, context.getNamingToken(), this.getClass().getClassLoader());
} catch (NamingException var5) {
}
this.startDaemonAwaitThread();
} catch (Exception var6) {
this.stopSilently();
this.destroySilently();
throw new WebServerException("Unable to start embedded Tomcat", var6);
}
}
}
2、我们对嵌入式容器的配置修改是怎么生效的?
(1)修改
package org.springframework.boot.autoconfigure.web;下的ServerProperties对应的配置
(2)WebServerFactoryCustomizer Web服务器工厂自定义程序
@Configuration( proxyBeanMethods = false
)
@AutoConfigureOrder(-2147483648)
@ConditionalOnClass({ServletRequest.class})
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@EnableConfigurationProperties({ServerProperties.class})
//导入了BeanPostProcessorsRegistrar,给容器中导入一些组件
//导入了WebServerFactoryCustomizerBeanPostProcessor
//后置处理器:bean初始化前后(刚创建完对象,还没属性赋值)执行初始化工作
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class})public class ServletWebServerFactoryAutoConfiguration {
WebServerFactoryCustomizer ...TomcatWebServerFactoryCustomizer定制器帮我们修改了servlet容器的配置
//初始化之前
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { //如果当前初始化的是一个WebServerFactory类型的组件
if (bean instanceof WebServerFactory) {
this.postProcessBeforeInitialization((WebServerFactory)bean);
}
return bean;
}
private void postProcessBeforeInitialization(WebServerFactory webServerFactory) { //获取所有的定制器,调用每一个定制器的customize方法来给servlet容器进行赋值
((Callbacks)LambdaSafe.callbacks(WebServerFactoryCustomizer.class, this.getCustomizers(), webServerFactory, new Object[0]).withLogger(WebServerFactoryCustomizerBeanPostProcessor.class)).invoke((customizer) -> {
customizer.customize(webServerFactory);
});
}
private Collection<WebServerFactoryCustomizer<?>> getCustomizers() { if (this.customizers == null) {
//从容器中获取所有WebServerFactoryCustomizer类型的组件
//定制servlet容器,给容器中可以添加一个WebServerFactoryCustomizer类型的组件
this.customizers = new ArrayList(this.getWebServerFactoryCustomizerBeans());
this.customizers.sort(AnnotationAwareOrderComparator.INSTANCE);
this.customizers = Collections.unmodifiableList(this.customizers);
}
return this.customizers;
}
private Collection<WebServerFactoryCustomizer<?>> getWebServerFactoryCustomizerBeans() { return this.beanFactory.getBeansOfType(WebServerFactoryCustomizer.class, false, false).values();
}
步骤:
1`springboot根据导入的依赖情况
@ConditionalOnClass({Servlet.class, Tomcat.class, UpgradeProtocol.class})
给容器中添加相应的AbstractServletWebServerFactory容器工厂
(TomcatServletWebServerFactory)
2`容器中某个组件要创建对象就会惊动后置处理器
WebServerFactoryCustomizerBeanPostProcessor
只要是嵌入式的servlet容器工厂,后置处理器就工作
F4出现继承树
3`后置处理器,从容器中获取所有的
WebServerFactoryCustomizer
调用定制器的定制方法
public class ServletWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered { private final ServerProperties serverProperties;
public ServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}
public int getOrder() {
return 0;
}
public void customize(ConfigurableServletWebServerFactory factory) {
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
ServerProperties var10001 = this.serverProperties;
var10001.getClass();
map.from(var10001::getPort).to(factory::setPort);