Spring 启动 - 等待网络服务器启动
Spring Boot - Wait for web server to start
在我的 Spring 引导应用程序中,我需要等到(默认 Tomcat)网络服务器完全初始化并准备好接收流量,然后我才能向其他应用程序发送消息,告诉它们发送 HTTP向我提出请求(特别是一个监控系统,它命中了我的/health
)。
我已经尝试将向其他应用程序发送消息的逻辑放在 ApplicationListener<ContextRefreshedEvent>
中,但现在还为时过早。其他应用程序尝试向我发出请求但失败了。现在我已经在 onApplicationEvent
中设置了延迟,这很有效,但它很老套而且很活泼。
我也试过添加一个 ServletContextInitializer
但它触发得更早。
我假设我需要使用 Tomcat API 但我想看看 Boot API 中是否有用于此目的的东西。
最简单的方法是在 SpringApplication.run()
完成 return 后发送消息。在Tomcat(或任何其他受支持的嵌入式容器)完全启动并侦听配置的端口之前,此方法不会return。然而,虽然这很简单,但它不是一个非常巧妙的方法,因为它混合了您的主要配置 class 和您的一些应用程序的 运行 时间逻辑的问题。
相反,您可以使用 SpringApplicationRunListener
。 finished()
在 Tomcat 完全启动并侦听配置的端口之前不会被调用。
创建一个名为 src/main/resources/META-INF/spring.factories
的文件,列出您的 运行 侦听器。例如:
org.springframework.boot.SpringApplicationRunListener=com.example.MyRunListener
使用所需的构造函数创建 运行 侦听器并实施 SpringApplicationRunListener
。例如:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
public class MyRunListener implements SpringApplicationRunListener {
public MyRunListener(SpringApplication application, String[] args) { }
@Override
public void starting() { }
@Override
public void environmentPrepared(ConfigurableEnvironment environment) { }
@Override
public void contextPrepared(ConfigurableApplicationContext context) { }
@Override
public void contextLoaded(ConfigurableApplicationContext context) { }
@Override
public void started(ConfigurableApplicationContext context) {
// Send message; Tomcat is running and listening on the configured port(s)
}
@Override
public void running(ConfigurableApplicationContext context) { }
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) { }
从 Spring Boot 1.3.0 开始,这也可以通过实施 ApplicationListener<ApplicationReadyEvent>
来实现
示例:
public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent>, Ordered {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
//do stuff now that application is ready
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
此外,如接受的答案中所述,您可以创建一个名为 src/main/resources/META-INF/spring.factories
的文件,列出您的 ApplicationListener
。例如:
org.springframework.context.ApplicationListener=com.example.MyApplicationListener
然而,在我的例子中,我只需要这个监听器在特定的配置文件下运行
所以我添加了以下 属性 到 application-<profile_name>.properties
context.listener.classes=com.example.MyApplicationListener
在我的 Spring 引导应用程序中,我需要等到(默认 Tomcat)网络服务器完全初始化并准备好接收流量,然后我才能向其他应用程序发送消息,告诉它们发送 HTTP向我提出请求(特别是一个监控系统,它命中了我的/health
)。
我已经尝试将向其他应用程序发送消息的逻辑放在 ApplicationListener<ContextRefreshedEvent>
中,但现在还为时过早。其他应用程序尝试向我发出请求但失败了。现在我已经在 onApplicationEvent
中设置了延迟,这很有效,但它很老套而且很活泼。
我也试过添加一个 ServletContextInitializer
但它触发得更早。
我假设我需要使用 Tomcat API 但我想看看 Boot API 中是否有用于此目的的东西。
最简单的方法是在 SpringApplication.run()
完成 return 后发送消息。在Tomcat(或任何其他受支持的嵌入式容器)完全启动并侦听配置的端口之前,此方法不会return。然而,虽然这很简单,但它不是一个非常巧妙的方法,因为它混合了您的主要配置 class 和您的一些应用程序的 运行 时间逻辑的问题。
相反,您可以使用 SpringApplicationRunListener
。 finished()
在 Tomcat 完全启动并侦听配置的端口之前不会被调用。
创建一个名为 src/main/resources/META-INF/spring.factories
的文件,列出您的 运行 侦听器。例如:
org.springframework.boot.SpringApplicationRunListener=com.example.MyRunListener
使用所需的构造函数创建 运行 侦听器并实施 SpringApplicationRunListener
。例如:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
public class MyRunListener implements SpringApplicationRunListener {
public MyRunListener(SpringApplication application, String[] args) { }
@Override
public void starting() { }
@Override
public void environmentPrepared(ConfigurableEnvironment environment) { }
@Override
public void contextPrepared(ConfigurableApplicationContext context) { }
@Override
public void contextLoaded(ConfigurableApplicationContext context) { }
@Override
public void started(ConfigurableApplicationContext context) {
// Send message; Tomcat is running and listening on the configured port(s)
}
@Override
public void running(ConfigurableApplicationContext context) { }
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) { }
从 Spring Boot 1.3.0 开始,这也可以通过实施 ApplicationListener<ApplicationReadyEvent>
示例:
public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent>, Ordered {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
//do stuff now that application is ready
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
此外,如接受的答案中所述,您可以创建一个名为 src/main/resources/META-INF/spring.factories
的文件,列出您的 ApplicationListener
。例如:
org.springframework.context.ApplicationListener=com.example.MyApplicationListener
然而,在我的例子中,我只需要这个监听器在特定的配置文件下运行
所以我添加了以下 属性 到 application-<profile_name>.properties
context.listener.classes=com.example.MyApplicationListener