目录
  • SpringBoot server.port配置原理
    • 1. autoConfigure
    • 2. embed tomcat如何使用
    • 小结一下
  • server.port不起作用

    SpringBoot server.port配置原理

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

    1. autoConfigure

    本质来源于自动配置

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

    SpringBoot server.port配置原理详解

    • 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<WebServerFactoryCustomizer<?>> 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<WebServerFactoryCustomizer<?>> 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<WebServerFactoryCustomizer<?>> 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设置好了。

    SpringBoot server.port配置原理详解

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

    ConfigurableServletWebServerFactory ,即TomcatServletWebServerFactory对象

    2. embed tomcat如何使用

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

    SpringBoot server.port配置原理详解

    就是 TomcatServletWebServerFactory

    SpringBoot server.port配置原理详解

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

    SpringBoot server.port配置原理详解

    小结一下

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

    server.port不起作用

    启动项目报错:

    org.apache.catalina.LifecycleException: Protocol handler start failed

    怀疑可能端口号冲突,在 application.properties 添加 server.port=8080 未生效

    立刻百度一圈没找到答案(感觉可能自己犯的错误太低级),突然想起可能是环境配置里面的配置给覆盖了

    #读取环境配置dev(开发)/pro(生产)/test(测试)
    spring.profiles.active=dev

    找到 application-dev.properties、application-prod.properties 发现果然存在

    按照配置的 dev 找到 application-dev.properties 修改 server.port=8080启动生效

    SpringBoot server.port配置原理详解

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。