source

스프링 부트 - 실행 중인 포트를 얻는 방법

ittop 2023. 3. 18. 09:20
반응형

스프링 부트 - 실행 중인 포트를 얻는 방법

스프링 부트 어플리케이션(임베디드 Tomcat 7 사용)을 사용하고 있으며,server.port = 0내 안에서application.properties임의의 포트를 가질 수 있게 됩니다.서버가 부팅되어 포트에서 실행되면 선택한 포트를 가져올 수 있어야 합니다.

사용할 수 없습니다@Value("$server.port")0이니까요이것은 단순한 정보인데, 왜 자바 코드에서 접근할 수 없는 것일까요?접속하려면 어떻게 해야 하나요?

다음과 같은 방법으로 관리 포트에 액세스할 수도 있습니까?

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

    @LocalServerPort
    int randomServerPort;

    @LocalManagementPort
    int randomManagementPort;

Spring's Environment가 이 정보를 보유하고 있습니다.

@Autowired
Environment environment;

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

표면상으로는 주석이 달린 필드를 주입하는 것과 같아 보입니다.@Value("${local.server.port}")(또는@LocalServerPort(동일합니다).이것에 의해, 콘텍스트가 완전하게 초기화될 때까지 값을 사용할 수 없기 때문에, 기동시에 자동 배선 장해가 발생하게 됩니다.여기서의 차이는, 이 콜은 애플리케이션 기동시에 호출되는 것이 아니라, 실행시의 비즈니스 로직으로 암묵적으로 행해지고 있기 때문에, 포토의 「lazy-fetch」에 의해서 정상적으로 해결된다는 것입니다.

@Dirk Lachowski에게 올바른 방향을 가르쳐 주셔서 감사합니다.그 해결책은 내가 생각했던 것만큼 우아하지는 않지만, 나는 그것을 작동시켰다.봄 문서를 읽으면 Embedded Servlet Container에서 들을 수 있습니다.InitializedEvent를 실행하여 서버가 가동되면 포트를 가져옵니다.이렇게 생겼는데...

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

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

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

저와 같은 앱을 구성한 다른 사람들이 제가 겪은 일로부터 혜택을 받을 수 있도록...

위의 솔루션 중 어느 것도 나에게 효과가 없었다.왜냐하면 나는./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에서 fat jar를 실행하면*.properties파일을 읽습니다../configdir 그리고 모든 것이 좋다.

이 속성 파일들은 이 파일들을 완전히 덮어쓰는 것으로 드러났습니다webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT설정@SpringBootTest내 스팍 스펙으로.아무리 노력해도webEnvironment로 설정하다.RANDOM_PORT스프링은 항상 포트 8080(또는 에서 설정한 값)에서 내장된 Tomcat 컨테이너를 기동합니다../config/*.properties파일)을 클릭합니다.

내가 이걸 극복할 수 있었던 유일한 방법은,properties = "server_port=0"@SpringBootTest★★★★

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

그 후 스프링은 마침내 랜덤 포트에서 Tomcat을 스핀업하기 시작했습니다.IMHO 이것은 봄 테스트 프레임워크의 버그입니다만, 이 문제에 대해서는 그들 자신의 의견이 있을 것이라고 확신합니다.

이게 도움이 됐으면 좋겠네요.

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;

  // ...
}

이 솔루션들 중 어느 것도 나에게 효과가 없었다.Swagger 구성 bean을 구성할 때 서버 포트를 알아야 했습니다.Server Properties를 사용하는 것이 효과적이었습니다.

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가 아님)를 사용합니다.

스프링 부츠 2 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」위의 답변은 스프링 부트2보다 먼저 동작합니다. 경우 값은 runtime만 .@Value("${server.port}")application.properties 파일에 기재되어 있습니다.서버가 실행되고 있는 실제 포토를 취득하려면 , 다음의 방법을 사용합니다.

    @Autowired
    private ServletWebServerApplicationContext server;

    @GetMapping("/server-port")
    public String serverPort() {

        return "" + server.getWebServer().getPort();
    }

부하 밸런싱이 로서 경우는, 「Eureka/Discovery」를 사용합니다.RestTemplate ★★★★★★★★★★★★★★★★★」WebClient위의 메서드는 정확한 포트 번호를 반환합니다.

현재 Spring 2.5.5에 있으며 Junit 4.13.2를 사용하고 있습니다.솔루션은 다음과 같습니다.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;

// tell Java the environment your testcase running is in Spring, 
// which will enable the auto configuration such as value injection
@RunWith(SpringRunner.class)
@SpringBootTest(
    class = Application.class, 
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SimpleWebTest {

    @LocalServerPort
    private int randomPort;

    @Test
    public void test() {
        // use randomPort ...
        System.out.println(randomPort);
    }

}

올바른 패키지를 Import했는지 확인하십시오.

import org.springframework.core.env.Environment;

[ Environment ]오브젝트를 사용합니다.

@Autowired
private Environment env;    // Environment Object containts the port number

 @GetMapping("/status")
  public String status()
    {
   return "it is runing on"+(env.getProperty("local.server.port"));
    }

서버 포트는 에서 얻을 수 있습니다.

HttpServletRequest
@Autowired
private HttpServletRequest request;

@GetMapping(value = "/port")
public Object getServerPort() {
   System.out.println("I am from " + request.getServerPort());
   return "I am from  " + request.getServerPort();
}
    

나는 그것을 일종의 대리 콩으로 해결했다.클라이언트는 필요할 때 초기화됩니다.그때쯤이면, 포토를 사용할 수 있게 됩니다.

@Component
public class GraphQLClient {

    private ApolloClient apolloClient;
    private final Environment environment;

    public GraphQLClient(Environment environment) {
        this.environment = environment;
    }

    public ApolloClient getApolloClient() {
        if (apolloClient == null) {
            String port = environment.getProperty("local.server.port");
            initApolloClient(port);
        }
        return apolloClient;
    }

    public synchronized void initApolloClient(String port) {
        this.apolloClient = ApolloClient.builder()
                .serverUrl("http://localhost:" + port + "/graphql")
                .build();
    }

    public <D extends Operation.Data, T, V extends Operation.Variables> GraphQLCallback<T> graphql(Operation<D, T, V> operation) {
        GraphQLCallback<T> graphQLCallback = new GraphQLCallback<>();
        if (operation instanceof Query) {
            Query<D, T, V> query = (Query<D, T, V>) operation;
            getApolloClient()
                    .query(query)
                    .enqueue(graphQLCallback);
        } else {
            Mutation<D, T, V> mutation = (Mutation<D, T, V>) operation;
            getApolloClient()
                    .mutate(mutation)
                    .enqueue(graphQLCallback);

        }
        return graphQLCallback;
    }
}

언급URL : https://stackoverflow.com/questions/30312058/spring-boot-how-to-get-the-running-port

반응형