代码之家  ›  专栏  ›  技术社区  ›  narendra-choudhary

Spring Boot:如何在运行时获取tomcat端口?

  •  1
  • narendra-choudhary  · 技术社区  · 7 年前

    我正在尝试使用Netflix OSS来实现微服务架构。我想记录 server.port 从…起 独自创立yml公司 文件位于 运行时 查看哪个实例正在为请求提供服务。

    我正在使用Java8。

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

    浏览stackoverflow后,我发现 this this 但这些解决方案并不奏效。

    我的引导程序。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)
    

    我想在中访问此端口号 main 方法 SomeService 班我该怎么做?

    3 回复  |  直到 7 年前
        1
  •  2
  •   davidxxx    7 年前

    静态场不会在弹簧中注入。
    您需要做的是首先将其设置为实例字段。
    然后,只有在Spring引导容器初始化它之后才能使用它。
    在带注释的方法中移动它们 @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
  •  2
  •   Ian Mc    7 年前

    您试图在Spring创建上下文之前访问上下文信息。删除静态引用,并从 @PostConstruct 块而非主块:

    @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
  •  0
  •   Monzurul Shimul    7 年前

    从引导中移动服务器端口配置。yml到应用程序。yml公司

    应用yml公司

    server:
      port: 8088
    

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