有时候我们可能需要在同一台机器上启动多个 Spring Boot 应用,而 Spring Boot 应用默认的端口号是 8080。所以这时候我们就需要修改 Spring Boot 应用的默认端口,修改 Spring Boot 默认端口有两种方式。下面就分别说一下这两种方式:
在 Spring Boot 中,我们可以通过修改 application.properties 属性文件,或修改 application.yml YAML 文件。如下:
(1)修改 application.properties 属性文件
server.port=8081
(2)修改 application.yml YAML 文件
server: port: 8081
启动 Spring Boot 应用,使用 http://localhost:8081 地址进行访问。
为什么上面可以通过配置实现修改 Spring Boot 的默认端口呢?这是由 Spring Boot 的 ServerProperties 类实现的,该类的部分代码如下:
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
	/**
	 * Server HTTP port.
	 */
	private Integer port;
	/**
	 * Network address to which the server should bind.
	 */
	private InetAddress address;
	// ... 忽略代码 ...
}在 ServerProperties 源码上面使用了 @ConfigurationProperties 注解修饰,这个注解会自动读取 Spring Boot 的默认配置文件 application.properties(或 application.yml)的值,且仅仅将带有 server 前缀的属性注入到该 Bean。因此,server.port 将会被注入到 ServerProperties 类的 port 成员变量。
使用 IDEA 打开 ServletWebServerFactoryCustomizer 类的源码,其中有个 customize(ConfigurableServletWebServerFactory factory) 方法,该方法源码如下:
@Override
public void customize(ConfigurableServletWebServerFactory factory) {
    PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
    map.from(this.serverProperties::getPort).to(factory::setPort);
    map.from(this.serverProperties::getAddress).to(factory::setAddress);
    map.from(this.serverProperties.getServlet()::getContextPath)
            .to(factory::setContextPath);
    map.from(this.serverProperties.getServlet()::getApplicationDisplayName)
            .to(factory::setDisplayName);
    map.from(this.serverProperties.getServlet()::getSession).to(factory::setSession);
    map.from(this.serverProperties::getSsl).to(factory::setSsl);
    map.from(this.serverProperties.getServlet()::getJsp).to(factory::setJsp);
    map.from(this.serverProperties::getCompression).to(factory::setCompression);
    map.from(this.serverProperties::getHttp2).to(factory::setHttp2);
    map.from(this.serverProperties::getServerHeader).to(factory::setServerHeader);
    map.from(this.serverProperties.getServlet()::getContextParameters)
            .to(factory::setInitParameters);
}上面代码中,map.from(this.serverProperties::getPort).to(factory::setPort) 用于将我们自定义的端口设置到 ConfigurableServletWebServerFactory 实例。注意:上面的双冒号(::)是 JDK8 语法。
并且,ServletWebServerFactoryCustomizer Bean 是在 ServletWebServerFactoryAutoConfiguration 配置配中进行配置,代码如下:
@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);
    }
    // ...忽略其他代码...
}上面介绍了通过属性配置或 YAML 配置 HTTP 端口,实际上这些端口最终是通过 ServletWebServerFactoryCustomizer 类的 customize(ConfigurableServletWebServerFactory factory) 方法进行设置的。
然而 customize(ConfigurableServletWebServerFactory factory) 方法的声明来自 WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> 接口,如果我们需要自己通过代码去设置 HTTP 端口,可以实现 WebServerFactoryCustomizer 接口,然后通过 @Configuration 和 @Bean 注解将自定义的类配置到 Spring Boot。
自定义 WebServerFactoryCustomizer 代码如下:
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        factory.setPort(8081);
    }
}创建一个自己的 @Configuration 类,将自定义的 MyWebServerFactoryCustomizer 类配置到 Spring Boot,例如:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfig {
    @Bean
    public MyWebServerFactoryCustomizer myWebServerFactoryCustomizer() {
        System.out.println("Init MyWebServerFactoryCustomizer()");
        return new MyWebServerFactoryCustomizer();
    }
}完成上面编码后,启动 Spring Boot 应用程序即可。
server.address:指定server绑定的地址
server.compression.enabled:是否开启压缩,默认为false
server.compression.excluded-user-agents:指定不压缩的user-agent,多个以逗号分隔,默认值为:text/html, text/xml, text/plain, text/css
server.compression.mime-types:指定要压缩的 MIME type,多个以逗号分隔
server.compression.min-response-size:执行压缩的阈值,默认为 2048
server.context-parameters.[param name]:设置 servlet context 参数
server.context-path:设定应用的 context-path(如设置 context-path=server.context-path,所以访问的路径前缀都要有/springboot)
server.display-name:设定应用的展示名称,默认: application
server.jsp-servlet.class-name:设定编译JSP用的servlet,默认: org.apache.jasper.servlet.JspServlet)
server.jsp-servlet.init-parameters.[param name]:设置 JSP servlet 初始化参数
server.jsp-servlet.registered:设定JSP servlet是否注册到内嵌的servlet容器,默认true
server.port:设定http监听端口
server.servlet-path:设定dispatcher servlet的监听路径,默认为: /
