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

9lowa7mx  于 2023-06-04  发布在  Java
关注(0)|答案(4)|浏览(534)

我正在尝试Netflix OSS来实现微服务架构。我想在运行时bootstrap.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方法中访问此端口号。我该怎么做?

cwdobuhd

cwdobuhd1#

Spring中不注入静态字段。
您需要做的是首先使其成为示例字段。
然后你必须在Sping 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);
    }

}
nle07wnf

nle07wnf2#

您正在尝试在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"));
}
wgeznvg7

wgeznvg73#

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

application.yml

server:
  port: 8088

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

flseospp

flseospp4#

我也遇到了同样的问题,并找到了这个解决方案来获取我的www.example.com文件中设置的server.port值application.properties:

@SpringBootApplication
public class MyApp {

    private static final Logger LOG = LogManager.getLogger();

        public static void main(String[] args) {
            var app = new SpringApplication(MyApp .class);
            app.setLogStartupInfo(false);
            String serverPort = app.run(args).getEnvironment().getProperty("server.port");
            LOG.info("=== Server is up on port {} ===", serverPort);
        }
    }

我有点晚了,但我希望这对你有帮助:)

相关问题