Spring 引导:如何在运行时获取 tomcat 端口?
Spring Boot: How do get tomcat port at runtime?
我正在尝试使用 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
在 Whosebug 上浏览后,我发现 and 但这些解决方案均无效。
我的 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
class 的 main
方法中访问这个端口号。我该怎么做?
您正试图在 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"));
}
静态字段未注入 Spring。
您需要做的是先将其设为实例字段。
然后你必须在 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);
}
}
将您的服务器端口配置从 bootstrap.yml 移动到 application.yml
application.yml
server:
port: 8088
通常 bootstrap.yml 包含两个属性:配置服务器的位置 (spring.cloud.config.uri) 和应用程序的名称 (spring.application.name)。启动时,Spring Cloud 使用应用程序的名称对配置服务器进行 HTTP 调用,并检索回该应用程序的配置。另一方面,application.yml 包含标准应用程序配置 - 通常是默认配置,因为在 bootstrap 过程中检索到的任何配置都将覆盖此处定义的配置。
我正在尝试使用 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
在 Whosebug 上浏览后,我发现
我的 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
class 的 main
方法中访问这个端口号。我该怎么做?
您正试图在 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"));
}
静态字段未注入 Spring。
您需要做的是先将其设为实例字段。
然后你必须在 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);
}
}
将您的服务器端口配置从 bootstrap.yml 移动到 application.yml
application.yml
server:
port: 8088
通常 bootstrap.yml 包含两个属性:配置服务器的位置 (spring.cloud.config.uri) 和应用程序的名称 (spring.application.name)。启动时,Spring Cloud 使用应用程序的名称对配置服务器进行 HTTP 调用,并检索回该应用程序的配置。另一方面,application.yml 包含标准应用程序配置 - 通常是默认配置,因为在 bootstrap 过程中检索到的任何配置都将覆盖此处定义的配置。