When you set server.port=0
in your Spring Boot application, the server will start on a random available port. Here's how to get the actual port being used:
Best Ways to Get the Random Port
1. Using ServletWebServerApplicationContext
(Recommended)
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.stereotype.Component; @Component public class RandomPortProvider { private final ServletWebServerApplicationContext serverContext; public RandomPortProvider(ServletWebServerApplicationContext serverContext) { this.serverContext = serverContext; } public int getAssignedPort() { return serverContext.getWebServer().getPort(); } }
2. Using @LocalServerPort
import org.springframework.boot.web.server.LocalServerPort; import org.springframework.stereotype.Component; @Component public class RandomPortProvider { @LocalServerPort private int actualPort; public int getPort() { return actualPort; } }
3. In Tests (Using Spring Boot Test Utilities)
If you're writing tests:
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.junit.jupiter.api.Test; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class MyIntegrationTest { @LocalServerPort private int randomPort; @Test public void testWithRandomPort() { System.out.println("Server is running on port: " + randomPort); // Your test code here } }
Important Notes
The
@Value("${server.port}")
approach won't work for random ports - it will return 0, not the actual assigned port.These methods will give you the actual port:
After the application context has started
After the server is initialized
If you need the port very early in the startup process (like in a
CommandLineRunner
orApplicationRunner
), make sure to get it after the server has started.
Example Usage in Application Startup
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.stereotype.Component; @Component public class PortLogger implements CommandLineRunner { private final ServletWebServerApplicationContext webServerAppCtxt; public PortLogger(ServletWebServerApplicationContext webServerAppCtxt) { this.webServerAppCtxt = webServerAppCtxt; } @Override public void run(String... args) { int port = webServerAppCtxt.getWebServer().getPort(); System.out.println("Server is running on port: " + port); } }
This approach is reliable whether you're using a fixed port or server.port=0
.
----------------------------------------------------------
Below is a sample how to get it
package com.example.greet_service_with_eureka.config;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class PortLogger implements CommandLineRunner {
private final ServletWebServerApplicationContext webServerAppCtxt;
private int port;
public PortLogger(ServletWebServerApplicationContext webServerAppCtxt) {
this.webServerAppCtxt = webServerAppCtxt;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Override
public void run(String... args) {
setPort(webServerAppCtxt.getWebServer().getPort());
System.out.println("Server is running on port: " + port);
}
}
package com.example.greet_service_with_eureka.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
@Autowired
private ServerProperties serverProperties;
public int getServerPort() {
return serverProperties.getPort();
}
}
package com.example.greet_service_with_eureka.controller;
import com.example.greet_service_with_eureka.config.MyComponent;
import com.example.greet_service_with_eureka.config.PortLogger;
import com.example.greet_service_with_eureka.model.Greet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetController {
private String message = "Demo with RestTemplate";
@Value("${server.port}")
private String serverPort;
@Autowired
MyComponent myComponent;
@Autowired
PortLogger portLogger;
@RequestMapping("/greet")
public Greet greet() {
System.out.println("### code 101 Inside greet");
return new Greet(message +"="+serverPort +" /from code="+myComponent.getServerPort() +" /fromCommandLiner="+portLogger.getPort());
}
}
Test greet with
http://localhost:62410/greet
Note:port is random
Yo can see only from you can get the port CommandLineRunner
output would like
{"message": "Demo with RestTemplate=0 /from code=0 /fromCommandLiner=62410"}
No comments:
Post a Comment