Как я могу получить порт сервера во время выполнения в Spring Webflux?

У меня есть приложение Spring Webflux с Spring Boot версии 2.3.5.

Как я могу получить порт сервера для запуска контейнера Netty во время выполнения? (Не в тестах)

Примечание: ни @Value("${server.port}") ни @Value("${local.server.port}") не работают, если порт не указан в конфигурации.

это может быть ответом на ваш вопрос: stackoverflow.com/questions/38916213/…

zlaval 16.12.2020 16:25

@zlaval, спасибо за ссылку! Однако, как упоминается в комментарии под верхним ответом, environment.getProperty("server.port"); не работает и по сути совпадает с подходом @Value.

fyrkov 16.12.2020 16:31

Также странно, что Spring Boot позволяет получить порт управления, обратившись к этому свойству во время выполнения: docs.spring.io/spring-boot/docs/current/reference/html/…, но не позволяет получить основной порт Netty таким же образом.

fyrkov 16.12.2020 16:35

прочитайте, второй ответ использует не свойство, а событие приложения, которое предпочтительнее, поскольку свойство может быть нулевым.

zlaval 16.12.2020 16:44

я думаю, это потому, что если вы установите свойство приложения, то Spring установит для него значение netty, но если нет, он не запишет его обратно в приложение

zlaval 16.12.2020 16:46

Если свойство не задано явно, его невозможно получить. Единственный выход – реагировать на событие. Порт управления также можно вводить/получать только в том случае, если это что-то другое по умолчанию. Таким образом, единственный способ получить его — использовать вышеупомянутое событие, или всегда явно определять порт, или вводить ServerProperties и принимать значение по умолчанию, если оно не установлено.

M. Deinum 16.12.2020 16:50

@M.Deinum M.Deinum после небольшого исследования кажется, что ReactiveWebServerApplicationContext возвращает текущий порт.

zlaval 16.12.2020 17:12
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
7
1 459
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Один из способов, который я нашел, — это org.springframework.boot.web.embedded.netty.NettyWebServer#start, и он выглядит как прослушиватель определенного события:

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

Однако я нахожу это не очень элегантным и задаюсь вопросом, есть ли лучшие способы.

Ответ принят как подходящий

После того, как я заглянул в библиотеку загрузки Spring, я обнаружил, что есть файл ReactiveWebServerApplicationContext. Он может дать вам порт.

@Autowired
private ReactiveWebServerApplicationContext server;

@GetMapping
public Flux<YourObject> getSomething() {
    var port = server.getWebServer().getPort());
    ...
}

Другие вопросы по теме