SpringBoot退出时执行相关代码

背景

我的一个SpringBoot Web应用(简称主应用),收到请求之后,会启动另外一个Java Web应用(简称子应用)。

当我们通过Ctrl + C、SpringBoot Actuator的shutdown接入端,或任务管理器“掐”掉我的主应用时,由主应用启动的子应用并不会退出,成为“游离”的状态,一直占据着某个TCP端口。

因此需要在主应用退出时,可以执行一些代码,可以“杀”掉主应用启动的子进程。

方案

在Spring容器销毁的时候,就会回调这个被@PreDestroy注解的方法:

1
2
3
4
5
6
7
@PreDestroy
public void onDestroy()
{
System.out.println("Spring Container is destroyed!" + System.lineSeparator() + "Application with pid " + new ApplicationPid() + " is destroyed!");

ExecutionService.killWithPid(ImmutableSet.of(Integer.parseInt(new ApplicationPid().toString())));
}

参考

Windows终止某个进程以及启动的子进程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void killWithPid(Set<Integer> pids)
{
for (Integer pid : pids)
{
try
{
Process process = Runtime.getRuntime().exec("taskkill /F /T /pid " + pid + "");
InputStream inputStream = process.getInputStream();
List<String> lines = IOUtils.readLines(inputStream, Charset.defaultCharset());
for (String line : lines)
{
log.info(line);
}
}
catch (IOException e)
{
log.error("执行杀死进程ID命令失败,详见:", e);
}
}
}