Подтвердить что ты не робот

Spring Загрузка - как получить текущий порт

У меня есть приложение загрузки spring (с использованием встроенного tomcat 7), и я установил server.port = 0 в мой application.properties, чтобы у меня был случайный порт. После того, как сервер загрузился и запущен на порту, мне нужно получить порт, который был выбран.

Я не могу использовать @Value("$server.port"), потому что он равен нулю. Это, казалось бы, простая часть информации, поэтому почему я не могу получить доступ к ней из своего java-кода? Как я могу получить к нему доступ?

4b9b3361

Ответ 1

Спасибо @Dirk Lachowski за то, что указали мне в правильном направлении. Решение не так элегантно, как мне бы хотелось, но я получил его работу. Читая документы spring, я могу прослушивать EmbeddedServletContainerInitializedEvent и получать порт после запуска и запуска сервера. Вот как это выглядит -

import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;




    @Component
    public class MyListener implements ApplicationListener<EmbeddedServletContainerInitializedEvent> {

      @Override
      public void onApplicationEvent(final EmbeddedServletContainerInitializedEvent event) {
          int thePort = event.getEmbeddedServletContainer().getPort();
      }
    }

Ответ 2

Можно ли также получить доступ к порту управления, например:

  @SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT)
  public class MyTest {

    @LocalServerPort
    int randomServerPort;

    @LocalManagementPort
    int randomManagementPort;

Ответ 3

Spring Среда содержит эту информацию для вас.

@Autowired
Environment environment;

String port = environment.getProperty("local.server.port");

На поверхности это выглядит так же, как впрыскивание поля, аннотированного @Value("${local.server.port}") (или @LocalServerPort, что является идентичным), в результате чего при запуске возникает отказ автоувеличивания, поскольку значение недоступно до тех пор, пока контекст не будет полностью инициализирован. Разница здесь в том, что этот вызов неявно делается в бизнес-логике времени выполнения, а не вызван при запуске приложения, и, следовательно, "ленивая выборка" порта разрешает нормально.

Ответ 4

Вы можете получить порт, который используется встроенным экземпляром Tomcat во время тестов, введя значение local.server.port как таковое:

// Inject which port we were assigned
@Value("${local.server.port}")
int port;

Ответ 5

Просто так, что другие, которые настроили свои приложения, такие как мои, выиграли от того, что я прошел...

Ни один из вышеперечисленных решений не работал у меня, потому что у меня есть каталог ./config только под моей проектной базой с двумя файлами:

application.properties
application-dev.properties

В application.properties у меня есть:

spring.profiles.active = dev  # set my default profile to 'dev'

В application-dev.properties у меня есть:

server_host = localhost
server_port = 8080

Это так, когда я запускаю свою толстую банку из CLI, файлы *.properties будут считаны из каталога ./config, и все это хорошо.

Ну, оказывается, что эти файлы свойств полностью переопределяют параметр webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT в @SpringBootTest в моих спецификациях Spock. Независимо от того, что я пытался, даже с webEnvironment, установленным в RANDOM_PORT Spring, всегда будет запускаться встроенный контейнер Tomcat на порт 8080 (или любое другое значение, которое я установил бы в своих файлах ./config/*.properties).

ТОЛЬКО, с которым я смог преодолеть это, было добавлено явное properties = "server_port=0" к аннотации @SpringBootTest в моих спецификациях интеграции Spock:

@SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "server_port=0")

Затем, и только тогда Spring, наконец, начал разворачивать Tomcat на случайном порту. IMHO - это ошибка проверки оболочки Spring, но я уверен, что у них будет собственное мнение по этому поводу.

Надеюсь, это помогло кому-то.

Ответ 6

Начиная с Spring Boot 1.4.0 вы можете использовать это в своем тесте:

import org.springframework.boot.context.embedded.LocalServerPort;

@SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT)
public class MyTest {

  @LocalServerPort
  int randomPort;

  // ...
}

Ответ 7

Ни одно из этих решений не помогло мне. Мне нужно было знать порт сервера при создании бина конфигурации Swagger. Использование ServerProperties работало для меня:

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.ApplicationPath;

import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.jaxrs.listing.ApiListingResource;
import io.swagger.jaxrs.listing.SwaggerSerializers;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;

@Component
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig 
{
    @Inject
    private org.springframework.boot.autoconfigure.web.ServerProperties serverProperties;

    public JerseyConfig() 
    {
        property(org.glassfish.jersey.server.ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
    }

    @PostConstruct
    protected void postConstruct()
    {
        // register application endpoints
        registerAndConfigureSwaggerUi();
    }

    private void registerAndConfigureSwaggerUi()
    {
        register(ApiListingResource.class);
        register(SwaggerSerializers.class);

        final BeanConfig config = new BeanConfig();
        // set other properties
        config.setHost("localhost:" + serverProperties.getPort()); // gets server.port from application.properties file         
    }
}

В этом примере используется автоматическая настройка Spring Boot и JAX-RS (не Spring MVC).