복붙노트

[SPRING] Spring Boot - 실행중인 포트를 얻는 방법

SPRING

Spring Boot - 실행중인 포트를 얻는 방법

나는 스프링 부트 응용 프로그램 (내장 된 바람둥이 7 사용)을 가지고 있으며 임의의 포트를 가질 수 있도록 내 application.properties에 server.port = 0을 설정했습니다. 서버를 부팅하고 포트에서 실행 한 후에는 선택한 포트를 가져올 수 있어야합니다.

@Value ( "$ server.port")는 0이므로 사용할 수 없습니다. 이것은 겉보기에 간단한 정보이므로 Java 코드에서 액세스 할 수없는 이유는 무엇입니까? 어떻게 접근 할 수 있습니까?

해결법

  1. ==============================

    1.비슷한 방법으로 관리 포트에 액세스 할 수 있습니까 (예 :

    비슷한 방법으로 관리 포트에 액세스 할 수 있습니까 (예 :

      @SpringBootTest(classes = {Application.class}, webEnvironment = WebEnvironment.RANDOM_PORT)
      public class MyTest {
    
        @LocalServerPort
        int randomServerPort;
    
        @LocalManagementPort
        int randomManagementPort;
    
  2. ==============================

    2.Spring의 환경에는이 정보가있다.

    Spring의 환경에는이 정보가있다.

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

    표면적으로 이것은 @Value ( "$ {local.server.port}") (또는 동일한 @LocalServerPort) 주석이 달린 필드를 삽입하는 것과 동일하게 보이므로 값을 사용할 수 없으므로 시작시 autowiring 실패가 발생합니다 문맥이 완전히 초기화 될 때까지 차이점은이 호출이 응용 프로그램 시작시 호출되는 것이 아니라 런타임 비즈니스 논리에서 암시 적으로 만들어 지므로 포트의 '지연 페치'가 정상적으로 해결된다는 것입니다.

  3. ==============================

    3.저를 올바른 방향으로 향한 @Dirk Lachowski에게 감사드립니다. 그 해결책은 제가 좋아했을만큼 우아하지는 않지만, 효과가 있습니다. 스프링 문서를 읽으면 EmbeddedServletContainerInitializedEvent에서 수신 대기하고 서버가 실행 중일 때 포트를 가져올 수 있습니다. 여기에 그것이 어떻게 생겼는지 -

    저를 올바른 방향으로 향한 @Dirk Lachowski에게 감사드립니다. 그 해결책은 제가 좋아했을만큼 우아하지는 않지만, 효과가 있습니다. 스프링 문서를 읽으면 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();
          }
        }
    
  4. ==============================

    4.Spring Boot 1.4.0부터 테스트에서 이것을 사용할 수 있습니다 :

    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;
    
      // ...
    }
    
  5. ==============================

    5.local.server.port 값을 다음과 같이 주입하여 테스트 중에 임베디드 Tomcat 인스턴스가 사용하는 포트를 가져올 수 있습니다.

    local.server.port 값을 다음과 같이 주입하여 테스트 중에 임베디드 Tomcat 인스턴스가 사용하는 포트를 가져올 수 있습니다.

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

    6.마치 내가 겪은 것에서 이익을 얻는 것과 같은 앱을 구성한 다른 사람들 ...

    마치 내가 겪은 것에서 이익을 얻는 것과 같은 앱을 구성한 다른 사람들 ...

    위의 솔루션 중 아무 것도 나를 위해 일했습니다. 왜냐하면 ./config 디렉토리가 내 프로젝트 기반 아래에 2 개의 파일로되어 있기 때문입니다. 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에서 * fatal jar 파일을 실행할 때 * .properties 파일이 ./config 디렉토리에서 읽히고 모두 유용합니다.

    음,이 속성 파일은 Spock 사양의 @SpringBootTest에있는 webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT 설정을 완전히 오버라이드합니다. 내가 뭘 했건 상관없이 webEnvironment를 RANDOM_PORT로 설정해도 Spring은 항상 포트 8080 (또는 ./config/*.properties 파일에서 설정 한 값)의 임베디드 Tomcat 컨테이너를 시작합니다.

    내가 이것을 극복 할 수 있었던 유일한 방법은 내 Spock 통합 사양의 @SpringBootTest 주석에 명시 적 속성 = "server_port = 0"을 추가하는 것이 었습니다.

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

    그런 다음, 그리고 나서야 봄이 마침내 임의의 포트에서 Tomcat을 시작합니다. IMHO 이것은 Spring 테스트 프레임 워크 버그이지만, 이것에 대한 그들 자신의 견해를 가지고있을 것이라고 확신한다.

    희망이 사람을 도왔습니다.

  7. ==============================

    7.이 솔루션들 중 어느 것도 나를 위해 일하지 못했습니다. Swagger 구성 빈을 구성하는 동안 서버 포트를 알아야했습니다. ServerProperties 사용은 저에게 효과적이었습니다.

    이 솔루션들 중 어느 것도 나를 위해 일하지 못했습니다. 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         
        }
    }
    

    이 예제는 스프링 부트 자동 설정과 JAX-RS (스프링 MVC 아님)를 사용한다.

  8. from https://stackoverflow.com/questions/30312058/spring-boot-how-to-get-the-running-port by cc-by-sa and MIT license