应用场景
最近工作中碰到了一个业务场景,在一条条产生数据,并对数据进行处理的时候,需要对比当前批次和上一批数据,然后进行一些处理。但是碰到代码更新需要手动停止项目,或者程序异常退出等情况,内存中用作对比的上一批次的历史数据会丢失。这样会导致再重新启动项目时,又是新的开始,会导致数据不准确,所以需要对停止前的数据进行落地,在程序重新启动的时候,再次加载到内存中。
涉及知识点
- ShutDownHook,Java提供的钩子,可以接收信号,在程序停止时,启动指定的线程。
- Spring 对集合,构造函数的注入,以及注入顺序
- 如何在静态方法中进行注入
- 如何在项目初始化的时候执行操作
- 如何将json字符串解析为复杂格式数据
下面我们针对上述知识点进行简单的讲解
ShutDownHook
定义
Java 提供名为ShutdownHook 的钩子,能够允许你在程序正常退出前执行特定代码。 一般用于清理资源、输出日志、保护当前正在执行的任务的执行。ShutdownHook 是一个不立刻执行的Thread,当程序正常退出时它被执行,可以同时存在多个ShutdownHook。
触发条件
- 程序正常退出
- 使用System.exit()
- 终端使用Ctrl+C触发的中断
- 系统关闭
- 使用Kill pid命令干掉进程,其中kill -9 不会触发,针对windows taskkill -pid xxx -F 也不会触发
使用示例
//使用addShutdownHook()方法来注册
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
RedisService redisService = DemoApplication.context.getBean(RedisService.class);
redisService.insertData();
}));
使用addShutDownHook() 方法来注册,添加一个线程,执行你需要做的操作,这里我们是执行数据插入到Redis的操作。
应用
在SpringBoot的源码中有大量用到shutDownHook的地方,比如释放数据库连接,回收系统资源等。
Spring的自动注入
相信大家对自动注入应该很熟悉了,我们常用的写法就是在某个需要引用到的地方,对被引用的类加上@Service注解,在引用处声明一个对象,加上@AutoWired注解,Spring就会自动帮我们创建并注入我们需要的Bean。
对集合进行注入
但是还有另外一种使用场景,Spring会自动对集合对象,如Set,Map,List进行注入。例如: