知識庫 / Spring / Spring Boot RSS 訂閱

獲取 Spring Boot 中的運行端口

Spring Boot
HongKong
5
12:46 PM · Dec 06 ,2025

1. 概述

Spring Boot 應用嵌入了一個 Web 服務器,有時我們可能需要動態地發現 HTTP 端口。

在本教程中,我們將學習如何在 Spring Boot 應用中通過編程方式獲取 HTTP 端口。

2. 簡介

本指南將介紹...

2.1. 我們的 Spring Boot 應用程序

我們將創建一個簡單的 Spring Boot 應用程序示例,以快速演示如何在運行時發現 HTTP 端口的方法:

@SpringBootApplication
public class GetServerPortApplication {
    public static void main(String[] args) {
        SpringApplication.run(GetServerPortApplication.class, args);
    }
}

2.2. 設置端口的兩種場景

通常,配置 Spring Boot 應用程序的 HTTP 端口最直接的方法是定義端口在配置文件中,例如 application.propertiesapplication.yml 中。

例如,在 application.properties 文件中,我們可以將應用程序運行的端口設置為 7777

server.port=7777

當然,以下是翻譯後的內容:

或者,與其定義一個固定的端口,我們可以讓 Spring Boot 應用在隨機端口上運行,通過將 "0" 設置為 "server.port" 屬性的值來實現:

server.port=0

接下來,我們來探討兩個場景並討論如何通過編程方式在運行時獲取端口。

在本教程中,我們將通過單元測試發現服務器端口。

3. 運行時固定端口

讓我們創建一個名為 application-fixedport.properties 的屬性文件,並在其中定義一個固定的端口 7777

server.port=7777

接下來,我們將嘗試在一個單元測試類中獲取端口:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = GetServerPortApplication.class,
  webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ActiveProfiles("fixedport")
public class GetServerFixedPortUnitTest {
    private final static int EXPECTED_PORT = 7777;
    ....
}

在查看測試方法之前,我們先快速瞭解一下測試類的註解:

  • @RunWith(SpringRunner.class) – 這將 JUnit 測試與 Spring 的 TestContext 結合
  • @SpringBootTest( … SpringBootTest.WebEnvironment.DEFINED_PORT) – 在 SpringBootTest 中,我們使用 DEFINED_PORT 來啓動嵌入式 Web 服務器
  • @ActiveProfiles(“fixedport”) – 通過此註解,我們啓用了 Spring 配置文件 “fixedport

3.1. 使用 <em @Value(“${server.port}”) 註解

由於 <em application-fixedport.properties 文件將被加載,我們可以使用 <em @Value 註解獲取 “<em server.port” 屬性:

@Value("${server.port}")
private int serverPort;

@Test
public void givenFixedPortAsServerPort_whenReadServerPort_thenGetThePort() {
    assertEquals(EXPECTED_PORT, serverPort);
}

3.2. 使用 ServerProperties

ServerProperties 包含嵌入式 Web 服務器的屬性,例如端口、地址和服務器頭信息。

我們可以注入 ServerProperties 組件並從中獲取端口:

@Autowired
private ServerProperties serverProperties;

@Test
public void givenFixedPortAsServerPort_whenReadServerProps_thenGetThePort() {
    int port = serverProperties.getPort();
 
    assertEquals(EXPECTED_PORT, port);
}

據目前為止,我們已經學習了兩種在運行時獲取固定端口的方法。接下來,讓我們看看如何在隨機端口場景中發現端口。

4. 運行時獲取隨機端口

現在,讓我們創建一個新的屬性文件 application-randomport.properties

server.port=0

如上代碼所示,我們允許 Spring Boot 在 Web 服務器啓動時隨機選擇一個空閒端口。

同樣地,讓我們創建一個新的單元測試類:

....
@ActiveProfiles("randomport")
public class GetServerRandomPortUnitTest {
...
}

這裏,我們需要激活“randomport” Spring 配置文件,以加載相應的屬性文件。

我們已經學習了兩種在運行時發現固定端口的方法。但是,它們無法幫助我們獲取隨機端口:

@Value("${server.port}")
private int randomServerPort;

@Test
public void given0AsServerPort_whenReadServerPort_thenGet0() {
    assertEquals(0, randomServerPort);
}

@Autowired
private ServerProperties serverProperties;

@Test
public void given0AsServerPort_whenReadServerProps_thenGet0() {
    int port = serverProperties.getPort();
 
    assertEquals(0, port);
}

正如這兩個測試方法所示,both @Value(“${server.port}”)serverProperties.getPort() 都報告端口為“0”。 顯然,這並不是我們期望的端口。

4.1. 使用 ServletWebServerApplicationContext

Spring Boot 在嵌入式 Web 服務器啓動時,會啓動一個 ServletWebServerApplicationContext

因此,我們可以從上下文對象中獲取 WebServer,從而獲取服務器信息或操作服務器:

@Autowired
private ServletWebServerApplicationContext webServerAppCtxt;

@Test
public void given0AsServerPort_whenReadWebAppCtxt_thenGetThePort() {
    int port = webServerAppCtxt.getWebServer().getPort();
 
    assertTrue(port > 1023);
}

在上述測試中,我們檢查端口是否大於 1023。這是因為 0-1023 是系統端口。

4.2. 處理 ServletWebServerInitializedEvent 事件

Spring 應用可以發佈各種事件,並且 事件監聽器 處理這些事件。

當嵌入式 Web 服務器啓動時,將會發佈一個 ServletWebServerInitializedEvent 事件。該事件包含有關 Web 服務器的信息。

因此,我們可以創建一個 事件監聽器 以從該事件中獲取端口號:

@Service
public class ServerPortService {
    private int port;

    public int getPort() {
        return port;
    }

    @EventListener
    public void onApplicationEvent(final ServletWebServerInitializedEvent event) {
        port = event.getWebServer().getPort();
    }
}

我們可以將服務組件注入到測試類中,以便快速獲取隨機端口:

@Autowired
private ServerPortService serverPortService;

@Test
public void given0AsServerPort_whenReadFromListener_thenGetThePort() {
    int port = serverPortService.getPort();
 
    assertTrue(port > 1023);
}

5. 結論

通常,我們會在屬性文件或 YAML 文件中配置 Spring Boot 應用程序的服務器端口,其中我們可以設置固定端口或隨機端口。

在本文中,我們討論了在運行時獲取固定端口和隨機端口的不同方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.