我的项目从使用Java 8和Spring Boot 2.0.4迁移到Java 11和Spring Boot 2.1.0。在使用Java 8和Spring Boot 2.0.4构建应用并在Docker / Docker Compose中运行时,会调用@PostConstruct
注释的方法,但是在迁移到Java 11和Spring Boot 2.1.0后,不再调用@PreDestroy
注释的方法。
我已经尝试按照这里的说明,从注释切换到实现InitializingBean
和DisposableBean
,但���不会调用DisposableBean.destroy
方法。
我还尝试添加依赖项javax.annotation-api版本1.3.2,但结果是相同的。
如何复现:
创建一个最小的Spring应用程序,并具有生命周期bean:
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class Life implements InitializingBean, DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("--- Life.shutdown");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("--- Life.startup");
}
}
从目标子文件夹启动Spring应用程序:
cd target
java -jar demo-0.0.1-SNAPSHOT.jar
当应用程序使用Ctrl+C停止时,会调用DisposableBean.destroy方法。
返回到父文件夹:
cd ..
使用Maven启动Spring应用程序:
mvn spring-boot:run
当应用程序使用 Ctrl+C 停止时,会调用 DisposableBean.destroy。
Dockerfile:
FROM openjdk:11.0.1-jre-slim
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT java -jar /app.jar
构建、运行和停止Docker镜像:
docker build -t demo .
docker run -p 8080:8080 demo
docker ps
docker stats 3ca5b804ab13
docker stop 3ca5b804ab13
docker logs 3ca5b804ab13
当应用程序使用docker stop停止时,不会调用DisposableBean.destroy。
docker-compose.yml:
demo:
image: demo
ports:
- '8080:8080'
使用Docker Compose运行Docker镜像(模拟OpenShift):
docker-compose up
docker-compose down
demo_demo_1 exited with code 137
当使用docker-compose down停止应用程序时,DisposableBean.destroy不会被调用。
我怀疑Docker在发出SIGKILL之前正在尝试SIGTERM,因为10秒的延迟后容器才被杀死。
SIGKILL
杀死 JVM 吗? - Karol Dowbecki