Spring Загрузка - как получить текущий порт
У меня есть приложение загрузки spring (с использованием встроенного tomcat 7), и я установил server.port = 0
в мой application.properties
, чтобы у меня был случайный порт. После того, как сервер загрузился и запущен на порту, мне нужно получить порт, который был выбран.
Я не могу использовать @Value("$server.port")
, потому что он равен нулю. Это, казалось бы, простая часть информации, поэтому почему я не могу получить доступ к ней из своего java-кода? Как я могу получить к нему доступ?
Ответы
Ответ 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).