Spring Boot 项目启动指定 HTTP 端口的几种方式
Posted carl-zhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot 项目启动指定 HTTP 端口的几种方式相关的知识,希望对你有一定的参考价值。
当我们进行业务开发的时候,通常都是需要暴露 HTTP 端口给前端页面进行调用。当我们使用 Spring Boot 进行 Web 业务开发的时候只需要引入以下 starter 依赖:
spring web 依赖 starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
引入了 spring-boot-starter-web
这个 starter 依赖,它会引入 tomcat 嵌入式容器。当我们使用 main
方法启动项目的时候它会内部启动 Tomcat 容器。这样我们就可以访问暴露的 restful
服务了。比如:
@RestController
@SpringBootApplication
public class Bootstrap
public static void main(String[] args)
SpringApplication.run(Bootstrap.class, args);
@GetMapping("test")
public String test()
return "hello, world";
然后我们可以访问:http://localhost:8080/test
这个地址就可以返回 hello, world
字符串。
这个是因为 Tomcat 默认使用的是 8080
这个端口.其实不管是默认的 Tomcat 容器还是 Jetty 或者 Undertow。Spring Boot 都对它们进行了抽象,可以通过 ServletWebServerFactory
来获取到 WebServer
。根据 classpath 中看 jar 包是依赖了 Tomcat、Jetty 或者 Undertow 来创建不同的容器。比如如果不使用 Tomcat 而想使用 Undertow,需要在 spring-boot-starter-web
这个 starter 当中排除 spring-boot-starter-tomcat
然后依赖 spring-boot-starter-undertow
。如下所示:
使用 Undertow 为 Web 容器
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
</dependencies>
从下面的启动日志当中我们就可以看出它是以 Undertow 这个 Web 容器来启动的。关于容器切换具体的原理可以参考我的另一篇博客 - Spring Boot 自动配置原理解析
从上面的章节当中,我们可以看到 Spring Boot 在启动容器的时候默认通过 8080 来暴露 http 服务的。如果我们需要指定暴露 http 服务的端口,我们应该怎么做呢?其实可以通过下面几种方式来指定我们暴露的 http 服务端口。
1、配置文件
我们可以在配置文件当中通过 server.port
来指定我们服务启动暴露的端口。
application.properties
server.port=8888
启动控制台,日志如下所示:
它的实现原理如下:
[server.port] ->
ServerProperties ->
ServletWebServerFactoryCustomizer ->
ConfigurableWebServerFactory ->
TomcatServletWebServerFactory
2、自定义 TomcatConnectorCustomizer
Spring 项目当中,可以通过 ServletWebServerFactory
来获取到 WebServer
.Tomcat 的实现类是 TomcatServletWebServerFactory
。在这个对象里面,可以通过 tomcatConnectorCustomizers
属性它是一个 Set<TomcatConnectorCustomizer>
。TomcatConnectorCustomizer
可以指定容器启动暴露的端口。
自定义 TomcatConnectorCustomizer
@Bean
public TomcatConnectorCustomizer customServerPortTomcatConnectorCustomizer()
return connector -> connector.setPort(8888);
启动控制台,日志如下所示:
3、自定义 WebServerFactoryCustomizer
TomcatServletWebServerFactory
不仅仅实现了 ServletWebServerFactory
,同时他也实现了WebServerFactory
。而且 Spring Boot 来提供了 WebServerFactoryCustomizer
这个接口来定制化WebServerFactory
, TomcatServletWebServerFactory
同时也是实现了WebServerFactory
的子接口 ConfigurableWebServerFactory
。这个接口是可以对 WebServer 进行配置化,包括 Web 容器的端口。
自定义 WebServerFactoryCustomizer
@Bean
public WebServerFactoryCustomizer customServerPortWebServerFactoryCustomizer()
return factory ->
if (factory instanceof ConfigurableWebServerFactory)
ConfigurableWebServerFactory webServerFactory = ConfigurableWebServerFactory.class.cast(factory);
webServerFactory.setPort(8888);
;
启动控制台,日志如下所示:
4、自定义 BeanPostProcessor
其实自定义 WebServerFactoryCustomizer
它的起始类是通过 WebServerFactoryCustomizerBeanPostProcessor
来进行自定义 WebServerFactory
。具体的代码逻辑如下:
我们也可以模仿它通过自定义 BeanPostProcess
来自定义 Web 容器暴露的端口。
自定义 BeanPostProcessor
@Bean
public BeanPostProcessor customServerPortBeanPostProcessor()
return new BeanPostProcessor()
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
if(bean instanceof ConfigurableWebServerFactory)
ConfigurableWebServerFactory webServerFactory = ConfigurableWebServerFactory.class.cast(bean);
webServerFactory.setPort(8888);
return bean;
;
启动控制台,日志如下所示:
5、指定传入请求参数
在 Idea 工具中添加项目请求参数: --server.port=8888
,如下所示:
启动控制台,日志如下所示:
它的实现原理是通过:org.springframework.boot.SpringApplication#configurePropertySources
把请求参数添加到 Spring 对环境变量的抽象 Environment 当中,然后通过以下方式把 server.port
设置到 Tomcat 容器当中:
把 Environment 值设置 Tomcat 的 port
- ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization
把 Environment 中的 [server.port] 绑定到 ServerProperties 这个 bean 当中
- ServletWebServerFactoryCustomizer#customize
把 ServerProperties 的 port 设置到 Tomcat 当中
- AbstractConfigurableWebServerFactory#setPort
6、指定传入系统参数
在 Idea 工具中添加系统变量: -Dserver.port=8888
,如下所示:
然后在 org.springframework.boot.SpringApplication#prepareEnvironment
调用 getOrCreateEnvironment()
之后,查看 environment
,通过如下公式获取 ConfigurableEnvironment
对象中的 server.port
environment.getPropertySources().get("systemProperties").getProperty("server.port")
如下所示:
然后通过以下方式把 server.port
设置到 Tomcat 容器当中:
把 Environment 值设置 Tomcat 的 port
- ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization
把 Environment 中的 [server.port] 绑定到 ServerProperties 这个 bean 当中
- ServletWebServerFactoryCustomizer#customize
把 ServerProperties 的 port 设置到 Tomcat 当中
- AbstractConfigurableWebServerFactory#setPort
以上就是博主现在已知的修改Spring Boot 项目启动指定 HTTP 端口的几种方式。
以上是关于Spring Boot 项目启动指定 HTTP 端口的几种方式的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 项目启动指定 HTTP 端口的几种方式
Spring Boot 项目启动指定 HTTP 端口的几种方式
Spring Boot# Spring Boot项目启动时,打印端口号项目名访问地址
Spring Boot# Spring Boot项目启动时,打印端口号项目名访问地址
eclipse创建spring boot项目,tomcat启动成功,但http://localhost:8080无法访问报错404解决方案