Spring 出现异常时不调用启动 onApplicationEvent(ContextClosedEvent 事件)
Spring Boot onApplicationEvent(ContextClosedEvent event) not called on in case of exception
下面是示例代码,即
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
log.info("Starting...");
mainThread.start();
mainThread.join();
log.info("Exiting...");
}
@EventListener
public void onApplicationEvent(ContextClosedEvent event) {
log.info("Inside on ApplicationEvent");
mainThread.interrupt();
log.info("Thread Interupted");
}
@Override
public void run() {
try {
someAppLogic.doLogic();
} catch (Exception e) {
if (e instanceof InterruptedException || e.getCause() instanceof InterruptedException) {
log.info("Interrupted...");
} else {
log.error("Exception occurred", e);
exitCode = 1;
}
}
}
- someAppLogic.doLogic();在 Spring 引导应用程序启动
时在 mainThread 中被调用
- 目标是在发生异常的情况下在 ApplicationEvent 的方法中让 mainThread 中断
在 someAppLogic.doLogic();退出代码为 1.
但问题是 onApplicationEvent 中的 main.interrupt() 永远不会 调用 以防出现异常
来自 运行 方法,即当 someAppLogic.doLogic() 抛出异常时。
这个 Spring 引导应用程序将部署在 Kubernetes 中,因此包含它的 pod 应该正常关闭。
所以问题是
如何处理 someAppLogic.doLogic(); 抛出的异常优雅地发送 exitcode 作为 1 ?
您需要在 ConfigurableApplicationContext 上调用 close() 才能发布 ContextClosedEvent。
//you need to figure out how to get hold of this object
private ConfigurableApplicationContext context;
@Override
public void run() {
try {
someAppLogic.doLogic();
} catch (Exception e) {
if (e instanceof InterruptedException || e.getCause() instanceof InterruptedException) {
log.info("Interrupted...");
} else {
log.error("Exception occurred", e);
exitCode = 1;
//call close
context.close();
}
}
}
下面是示例代码,即
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
log.info("Starting...");
mainThread.start();
mainThread.join();
log.info("Exiting...");
}
@EventListener
public void onApplicationEvent(ContextClosedEvent event) {
log.info("Inside on ApplicationEvent");
mainThread.interrupt();
log.info("Thread Interupted");
}
@Override
public void run() {
try {
someAppLogic.doLogic();
} catch (Exception e) {
if (e instanceof InterruptedException || e.getCause() instanceof InterruptedException) {
log.info("Interrupted...");
} else {
log.error("Exception occurred", e);
exitCode = 1;
}
}
}
- someAppLogic.doLogic();在 Spring 引导应用程序启动 时在 mainThread 中被调用
- 目标是在发生异常的情况下在 ApplicationEvent 的方法中让 mainThread 中断 在 someAppLogic.doLogic();退出代码为 1.
但问题是 onApplicationEvent 中的 main.interrupt() 永远不会 调用 以防出现异常 来自 运行 方法,即当 someAppLogic.doLogic() 抛出异常时。
这个 Spring 引导应用程序将部署在 Kubernetes 中,因此包含它的 pod 应该正常关闭。
所以问题是 如何处理 someAppLogic.doLogic(); 抛出的异常优雅地发送 exitcode 作为 1 ?
您需要在 ConfigurableApplicationContext 上调用 close() 才能发布 ContextClosedEvent。
//you need to figure out how to get hold of this object
private ConfigurableApplicationContext context;
@Override
public void run() {
try {
someAppLogic.doLogic();
} catch (Exception e) {
if (e instanceof InterruptedException || e.getCause() instanceof InterruptedException) {
log.info("Interrupted...");
} else {
log.error("Exception occurred", e);
exitCode = 1;
//call close
context.close();
}
}
}