前言
一般在服务器重新部署SpringBoot项目,无非就是用kill -9暴力停止进程,但会造成很多数据问题,如果遇到一些耗时或者正在处理交易类的业务时,直接导致数据异常,严重会导致一些预想不到的后果。针对这种情况也有很多解决办法,我这里只列举接口的方式,感觉这是比较方便的做法,就算是把接口暴露到了外网,只需要在接口里面做好权限校验,也能防止被外部调用,保证接口的安全性。
实现
SpringBoot 官方文档上,已经告诉开发者只需要实现特定接口即可监听到项目启动成功与关闭时的事件,相关接口如下:
CommandLineRunner接口:当应用启动成功后但在开始接受流量之前,会回调此接口的实现类,也可以实现ApplicationRunner接口,工作的方式与CommandLineRunner与之类似。
DisposableBean接口:当应用正要被销毁前,会回调此接口的实现类,也可以使用@PreDestroy注解,被标记的方法也会被调用。
基于此流程,我们可以创建一个服务监听类,用于监听到项目启动成功与关闭时的回调服务,示例代码如下:
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class AppListener implements CommandLineRunner, DisposableBean {
@Override
public void run(String... args) throws Exception {
System.out.println("应用启动成功,预加载相关数据....");
for (int i = 0; i < 30; i++){
Thread.sleep(1000);
System.out.println("业务---" + i);
}
}
@Override
public void destroy() throws Exception {
System.out.println("应用正在关闭,清理相关数据....");
}
}
每一个SpringApplication在启用的时候,都会向JVM注册一个关闭钩子shutdownhook,以确保ApplicationContext在退出的时候,通过这个勾子通知JVM,实现服务正常的关闭。
新建一个controller用于关闭服务
@RestController
public class ShutdownController implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
/**
* 关闭服务
*/
@GetMapping("/shutdown")
public void shutdownContext() {
((ConfigurableApplicationContext) context).close();
}
}
调用接口:http://localhost:8080/shutdown
此时会发现会等待项目的所有在运行的逻辑全部关闭后,再自动关闭整个服务。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)