4

I have a Spring Webflux application with Spring Boot ver 2.3.5

How can I get a server port of running Netty container at runtime? (Not in tests)

Note: nor @Value("${server.port}") neither @Value("${local.server.port}") do not work if the port is not specified in the configuration.

fyrkov
  • 2,245
  • 16
  • 41
  • this may be tha answer to your question: https://stackoverflow.com/questions/38916213/how-to-get-the-spring-boot-host-and-port-address-during-run-time – zlaval Dec 16 '20 at 15:25
  • @zlaval, thanks for the link! However as it is mentioned in the comment under the top answer `environment.getProperty("server.port");` is not working and essentially is the same as `@Value` approach. – fyrkov Dec 16 '20 at 15:31
  • It's also strange that Spring Boot allows getting management port by acessing this property at runtime: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#management.server.port , but does not allow to get the main Netty port in the same way. – fyrkov Dec 16 '20 at 15:35
  • read through, the second answer not use property but application event, which is prefered due to the property maybe null. – zlaval Dec 16 '20 at 15:44
  • i think its because if you set app property, then spring set it to netty, but if not, it not write back it to app prop – zlaval Dec 16 '20 at 15:46
  • If the property isn't explicitly set one cannot get it. The only way would be to react to an event. The management port is also only injectable/gettable if it is something else as the default. So the only way to get it is to use the aforementioned event **or** to always explicitly define the port **or** to inject the `ServerProperties` and assume the default when not set. – M. Deinum Dec 16 '20 at 15:50
  • @M.Deinum after a little research it seems that ReactiveWebServerApplicationContext give back the current port. – zlaval Dec 16 '20 at 16:12

2 Answers2

6

After I looking into the spring boot library, I found that there is a ReactiveWebServerApplicationContext. It can give you the port.

@Autowired
private ReactiveWebServerApplicationContext server;

@GetMapping
public Flux<YourObject> getSomething() {
    var port = server.getWebServer().getPort());
    ...
}
zlaval
  • 1,941
  • 1
  • 10
  • 11
2

One way I found to do is from org.springframework.boot.web.embedded.netty.NettyWebServer#start and looks like a listener to a certain event:

@Component
@Slf4j
public class ServerStartListener implements ApplicationListener<WebServerInitializedEvent> {

    @Override
    public void onApplicationEvent(WebServerInitializedEvent event) {
        // This is to exclude management port
        if (!"management".equals(event.getApplicationContext().getServerNamespace())) {
            log.info("Application started on port {}", event.getWebServer().getPort());
        }
    }
}

However, I find this not very elegant and wonder if there are better ways.

fyrkov
  • 2,245
  • 16
  • 41