Spring Boot server.port配置原理

前言

       我们经常配置server.port=xxx,但其实这是一个比较复杂的过程才生效的,这次讲讲生效的过程。

1. autoConfigure

本质来源于自动配置

org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration

Spring Boot server.port配置原理_第1张图片

TomcatServletWebServerFactory

为什么是这个类,核心是beanPostProcess原理

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

	/**
	 * Server HTTP port.
	 */
	private Integer port;

 beanPostProcess

public class WebServerFactoryCustomizerBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {

	private ListableBeanFactory beanFactory;

	private List> customizers;


	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (bean instanceof WebServerFactory) {
			postProcessBeforeInitialization((WebServerFactory) bean);
		}
		return bean;
	}

	
	@SuppressWarnings("unchecked")
	private void postProcessBeforeInitialization(WebServerFactory webServerFactory) {
		LambdaSafe.callbacks(WebServerFactoryCustomizer.class, getCustomizers(), webServerFactory)
				.withLogger(WebServerFactoryCustomizerBeanPostProcessor.class)
				.invoke((customizer) -> customizer.customize(webServerFactory));
	}

    private Collection> getCustomizers() {
		if (this.customizers == null) {
			// Look up does not include the parent context
			this.customizers = new ArrayList<>(getWebServerFactoryCustomizerBeans());
			this.customizers.sort(AnnotationAwareOrderComparator.INSTANCE);
			this.customizers = Collections.unmodifiableList(this.customizers);
		}
		return this.customizers;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private Collection> getWebServerFactoryCustomizerBeans() {
		return (Collection) this.beanFactory.getBeansOfType(WebServerFactoryCustomizer.class, false, false).values();
	}

 最终beanFactory.getBeansOfType(WebServerFactoryCustomizer.class, false, false).values()

WebServerFactoryCustomizer对象.customize(webServerFactory)

@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {

	@Bean
	public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
		return new ServletWebServerFactoryCustomizer(serverProperties);
	}

 这里就将port设置好了。

Spring Boot server.port配置原理_第2张图片

这里使用函数式编程,lambda表达式,将port的值设置进了

ConfigurableServletWebServerFactory ,即TomcatServletWebServerFactory对象

2. embed tomcat如何使用

 tomcat创建时,会通过getBean方式获取工厂

Spring Boot server.port配置原理_第3张图片

就是 TomcatServletWebServerFactory

Spring Boot server.port配置原理_第4张图片

然后设置connector,从TomcatServletWebServerFactory读取port,设置connector,设置结束

Spring Boot server.port配置原理_第5张图片 

总结

       Spring Boot在解耦的时候绕了很多弯,先@Bean factory对象,然后BeanPostProcess,然后启动embed tomcat 在factory 中new Tomcat 然后设置Connector,设置port。

你可能感兴趣的:(spring,boot)