1. 概要

Spring BootアプリケーションにはWebサーバーが組み込まれており、実行時にHTTPポートを検出したい場合があります。

このチュートリアルでは、Spring BootアプリケーションでプログラムでHTTPポートを取得する方法について説明します。

2. 序章

2.1. SpringBootアプリケーション

実行時にHTTPポートを検出する方法をすばやく示すために、簡単なSpring Bootアプリケーションの例を作成します。

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

2.2. ポートを設定する2つのシナリオ

通常、Spring BootアプリケーションのHTTPポート構成する最も簡単な方法は、構成ファイルapplication.propertiesまたはapplication.ymlでポートを定義することです。 。

たとえば、 application.properties ファイルでは、アプリケーションが実行されているポートとして7777を設定できます。

server.port=7777

または、固定ポートを定義する代わりに、「server.port」プロパティの値として「0」を設定することで、SpringBootアプリケーションをランダムポートで実行させることができます

server.port=0

次に、2つのシナリオを実行し、実行時にプログラムでポートを取得するさまざまな方法について説明します。

このチュートリアルでは、単体テストでサーバーポートを検出します。

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 では、組み込みWebサーバーにDEFINED_PORTを使用します
  • @ActiveProfiles(“ fixedport”) –このアノテーションを使用して、 Spring profile fixedport ”を有効にし、 application-fixedport.properties[ X170X]が読み込まれます

3.1. @Value(“ $ {server.port}”)アノテーションの使用

application-fixedport.properties ファイルがロードされるため、@Valueアノテーションを使用して「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);
}

これまで、実行時に固定ポートを取得する2つの方法を学びました。 次に、ランダムポートシナリオでポートを検出する方法を見てみましょう。

4. 実行時にランダムポートを取得する

今回は、別のプロパティファイルapplication-randomport.propertiesを作成しましょう。

server.port=0

上記のコードが示すように、Webサーバーの起動時にSpringBootがランダムに空きポートを選択できるようにします。

同じように、別の単体テストクラスを作成しましょう。

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

ここでは、「 randomport 」Springプロファイルをアクティブにして、対応するプロパティファイルをロードする必要があります。

実行時に固定ポートを検出する2つの方法を学びました。 ただし、ランダムポートを取得するのに役立ちません。

@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);
}

2つのテスト方法が示すように、 @Value( “$ {server.port}”)とserverProperties.getPort()の両方がポートとして「0」を報告します。明らかに、これは正しいポートではありません。期待。

4.1. ServletWebServerApplicationContextを使用する

組み込みWebサーバーが起動すると、SpringBootは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アプリケーションは、さまざまなイベントを公開でき、EventListenersがイベントを処理します。

組み込みWebサーバーが起動すると、ServletWebServerInitializedEventが公開されます。 このイベントには、Webサーバーに関する情報が含まれています。

したがって、 EventListener を作成して、このイベントからポートを取得できます。

@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. 結論

通常、Spring BootアプリケーションのサーバーポートはプロパティファイルまたはYAMLファイルで構成します。ここで、固定ポートまたはランダムポートのいずれかを設定できます。

この記事では、実行時に固定ポートとランダムポートを取得するためのさまざまなアプローチについて説明しました。

いつものように、記事の完全なソースコードは、GitHubから入手できます。