【问题标题】:Spring Boot: How do get tomcat port at runtime?Spring Boot:如何在运行时获取 tomcat 端口?
【发布时间】:2018-08-09 23:35:50
【问题描述】:

我正在尝试使用 Netflix OSS 来实现微服务架构。我想在 runtimebootstrap.yml 文件中记录 server.port,以查看哪个实例正在为请求提供服务。

我正在使用 Java8。

重要的库版本是:
* spring-boot-starter-web-1.5.8
* spring-boot-starter-tomcat-1.5.8
* tomcat-embed-core-8.5.23

在stackoverflow上浏览后,我找到了thisthis,但是这些解决方案都不起作用。

我的 bootstrap.yml 看起来像这样:

spring:
  application:
    name: some-service

server:
  port: ${port:8088}

我尝试了以下代码:

@SpringBootApplication
@EnableEurekaClient
@SuppressWarnings("javadoc")
public class SomeService {

    private static Logger logger  = LoggerFactory.getLogger(SomeService .class);

    @LocalServerPort
    private static int randomServerPort;

    @LocalManagementPort
    private static int randomManagementPort;

    @Autowired
    private static Environment environment;

    @Value("${server.port}")
    // @Value("${local.server.port}")
    private static int port;

    public static void main(String[] args) {
        SpringApplication.run(SomeService .class, args);

        logger.info("randomServerPort : {}", randomServerPort);
        logger.info("randomManagementPort : {}", randomManagementPort);
        logger.info("server.port : {}", port);
        logger.info("environment.getProperty(\"server.port\") : {}", environment.getProperty("server.port"));

}

对应的输出是:

randomServerPort : 0
randomManagementPort : 0
server.port : 0
java.lang.NullPointerException against environment.getProperty("server.port")

前三个日志语句记录 0,而最后一个则抛出 `NullPointerException*。

在运行时,端口在控制台的日志中打印为:

s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8088 (http)

我想在SomeService 类的main 方法中访问这个端口号。我该怎么做?

【问题讨论】:

    标签: java spring spring-boot tomcat8


    【解决方案1】:

    在 Spring 中不注入静态字段。
    您需要先将其设为实例字段。
    然后你必须在 Spring Boot 容器初始化它之后才能使用它。
    将它们移动到一个带有@PostConstruct 注释的方法中应该可以完成这项工作,因为它是在执行依赖注入之后调用的。

    @SpringBootApplication
    @EnableEurekaClient
    @SuppressWarnings("javadoc")
    public class SomeService {
    
        private static Logger logger  = LoggerFactory.getLogger(SomeService .class);
    
        @LocalServerPort
        private static int randomServerPort;
    
        @LocalManagementPort
        private static int randomManagementPort;
    
        @Autowired
        private static Environment environment;
    
        @Value("${server.port}")
        private int port;
    
        @PostConstruct
        public void postConstruct(){
            logger.info("randomServerPort : {}", randomServerPort);
            logger.info("randomManagementPort : {}", randomManagementPort);
            logger.info("server.port : {}", port);
            logger.info("environment.getProperty(\"server.port\") : {}", environment.getProperty("server.port"));
        }    
    
        public static void main(String[] args) {
            SpringApplication.run(SomeService .class, args);
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      您正试图在 Spring 创建上下文之前访问上下文信息。删除静态引用,并从 @PostConstruct 块而不是 main 访问数据:

      @Autowired
      private Environment environment;
      
      @Value("${server.port}")
      private int port;
      
      public static void main(String[] args) {
          SpringApplication.run(SomeService .class, args);
      }
      
      @PostConstruct
      public void init() {
          logger.info("server.port : {}", port);
          logger.info("environment.getProperty(\"server.port\") : {}", environment.getProperty("server.port"));
      }
      

      【讨论】:

        【解决方案3】:

        将您的服务器端口配置从 bootstrap.yml 移动到 application.yml

        application.yml

        server:
          port: 8088
        

        通常 bootstrap.yml 包含两个属性:配置服务器的位置 (spring.cloud.config.uri) 和应用程序的名称 (spring.application.name)。启动时,Spring Cloud 使用应用程序的名称对配置服务器进行 HTTP 调用,并取回该应用程序的配置。另一方面,application.yml 包含标准的应用程序配置 - 通常是默认配置,因为在引导过程中检索到的任何配置都将覆盖此处定义的配置。

        【讨论】:

        • 我之前只在 application.yml 中有server.port。但我面临着与上述问题相同的问题。由于 bootstrap.ymlapplication.yml 之前加载,我认为将 server.port 移动到 bootstrap.yml 可能会解决问题。但这并没有帮助。我会将server.port 移回 application.yml
        猜你喜欢
        • 2015-07-30
        • 2016-08-02
        • 2021-01-29
        • 2019-03-20
        • 2016-10-10
        • 2015-12-14
        • 2021-03-27
        • 2019-01-08
        • 2019-04-30
        相关资源
        最近更新 更多