Tomcat Spring启动-等待web服务器启动
在我的Spring Boot应用程序中,我需要等待(默认Tomcat)web服务器完全初始化并准备好接收流量,然后再向其他应用程序发送消息,告诉它们向我发送HTTP请求(特别是一个点击我的Tomcat Spring启动-等待web服务器启动,tomcat,spring-boot,Tomcat,Spring Boot,在我的Spring Boot应用程序中,我需要等待(默认Tomcat)web服务器完全初始化并准备好接收流量,然后再向其他应用程序发送消息,告诉它们向我发送HTTP请求(特别是一个点击我的/health)的监控系统) 我曾尝试将向其他应用程序发送消息的逻辑放在ApplicationListener中,但现在还为时过早。其他应用程序试图向我发出请求,但失败了。现在,我在applicationEvent的中延迟了一段时间,这是可行的,但它很有黑客味 我还尝试添加了一个ServletContextIn
/health
)的监控系统)
我曾尝试将向其他应用程序发送消息的逻辑放在ApplicationListener
中,但现在还为时过早。其他应用程序试图向我发出请求,但失败了。现在,我在applicationEvent的中延迟了一段时间,这是可行的,但它很有黑客味
我还尝试添加了一个ServletContextInitializer
,但它甚至更早就启动了
我假设我需要使用Tomcat API,但我想看看启动API中是否有用于此的内容。最简单的方法是在返回SpringApplication.run()
后发送消息。在Tomcat(或任何其他受支持的嵌入式容器)完全启动并侦听配置的端口之前,此方法不会返回。然而,尽管这很简单,但它并不是一种很好的方法,因为它混合了主配置类的关注点和应用程序的一些运行时逻辑
相反,您可以使用finished()
在Tomcat完全启动并在配置的端口上侦听之前不会被调用
创建一个名为src/main/resources/META-INF/spring.factories的文件,列出您的运行侦听器。例如:
org.springframework.boot.SpringApplicationRunListener=com.example.MyRunListener
org.springframework.context.ApplicationListener=com.example.MyApplicationListener
使用所需的构造函数创建运行侦听器,并实现SpringApplicationRunListener
。例如:
org.springframework.boot.SpringApplicationRunListener=com.example.MyRunListener
org.springframework.context.ApplicationListener=com.example.MyApplicationListener
package.com.example;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.SpringApplicationRunListener;
导入org.springframework.context.ConfigurableApplicationContext;
导入org.springframework.core.env.ConfigurableEnvironment;
公共类MyRunListener实现SpringApplicationRunListener{
公共MyRunListener(SpringApplication应用程序,字符串[]args){}
@凌驾
public void start(){}
@凌驾
public void environment已准备就绪(可配置环境){}
@凌驾
public void contextPrepared(ConfigurableApplicationContext上下文){}
@凌驾
public void contextLoaded(ConfigurableApplicationContext上下文){}
@凌驾
public void已启动(ConfigurableApplicationContext上下文){
//发送消息;Tomcat正在运行并在配置的端口上侦听
}
@凌驾
public void正在运行(ConfigurableApplicationContext上下文){}
@凌驾
public void失败(ConfigurableApplicationContext上下文,可丢弃异常){}
自Spring Boot 1.3.0以来,这也可以通过实现ApplicationListener
例如:
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;
}
}
然而,在我的例子中,我只需要在特定的配置文件下运行这个侦听器
因此,我将以下属性添加到application-.properties
context.listener.classes=com.example.MyApplicationListener
您是否看到:?此外,您可以将您的应用程序隐藏在LB后面,LB不会将您的应用程序放入其池中,直到对/health
的请求返回HTTP OK(200).Works很棒。我创建了另一个感兴趣的bean可以实现的接口,我的SpringApplicationRunListener
将它们从上下文中提取出来并调用它们,这样逻辑就可以保留在相关的bean中。这对我根本不起作用。finished()方法几乎是立即调用的,而且肯定是在应用程序启动和运行之前调用的。@onnoweb我看不出这会发生什么,因为在SpringApplication的末尾调用finished方法。运行处理。也许你可以问自己一个问题,显示finished比预期的更早被调用。我缩小了范围d关闭我的问题:ApplicationReadyEvent在Tomcat启动和运行之前被触发。使用CommandLineRunner而不是侦听ApplicationReadyEvent修复了我的问题。此接口已更新;较新的实现现在应该使用running
方法。