【SpringBoot】简述springboot项目启动数据加载内存中的三种方法

简介: SpringBoot提供了两个接口: CommandLineRunner 和 ApplicationRunner 。实现其中接口,就可以在工程启动时将数据库中的数据加载到内存。使用的场景有:加载配置项到内存中;启动时将字典或白名单数据加载到内存(或缓存到Redis中)。

一、前言

一般来说,SpringBoot工程环境配置放在properties文件中,启动的时候将工程中的properties/yaml文件的配置项加载到内存中。但这种方式改配置项的时候,需要重新编译部署,考虑到这种因素,今天介绍将配置项存到数据库表中,在工程启动时把配置项加载到内存中。

SpringBoot提供了两个接口: CommandLineRunnerApplicationRunner 。实现其中接口,就可以在工程启动时将数据库中的数据加载到内存。使用的场景有:加载配置项到内存中;启动时将字典或白名单数据加载到内存(或缓存到Redis中)。

二、加载方式

第一种:使用@PostConstruct注解(properties/yaml文件)。

第二种:使用@Order注解和CommandLineRunner接口。

第三种:使用@Order注解和ApplicationRunner接口。

注意事项

第二种和第三种,二者的官方javadoc一样,区别在于接收的参数不一样。CommandLineRunner的参数是最原始的参数,没有做任何处理。ApplicationRunner的参数是ApplicationArguments,是对原始参数做了进一步的封装。

三、代码示例

3.1 使用@PostConstruct注解

package com.example.demo.config;
import com.example.demo.service.ICodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class InitData1 {
    public static Map<Integer, String> codeMap = new HashMap<Integer, String>();
    @Autowired
    private ICodeService codeService;
    @PostConstruct
    public void init() {
        System.out.println("示例1:加载codeMap中......");
        // 查询数据库数据
        List<String> codeList = codeService.listAll();
        for (int i = 0; i < codeList.size(); i++) {
            codeMap.put(i, codeList.get(i));
        }
    }
    @PreDestroy
    public void destroy() {
        System.out.println("系统启动成功,codeMap加载完成!");
    }
}

3.2 CommandLineRunner接口

package com.example.demo.config;
import com.example.demo.service.ICodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Order(1) // 初始化加载优先级,数字越小优先级越高
public class InitData2 implements CommandLineRunner {
    public static Map<Integer, String> codeMap = new HashMap<Integer, String>();
    @Autowired
    private ICodeService codeService;
    @Override
    public void run(String... args) throws Exception {
        System.out.println("示例2:加载codeMap中......");
        // 查询数据库数据
        List<String> codeList = codeService.listAll();
        for (int i = 0; i < codeList.size(); i++) {
            codeMap.put(i, codeList.get(i));
        }
    }
}

3.3 ApplicationRunner接口

package com.example.demo.config;
import com.example.demo.service.ICodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Order(1) // 初始化加载优先级,数字越小优先级越高
public class InitData3 implements ApplicationRunner {
    public static Map<Integer, String> codeMap = new HashMap<Integer, String>();
    @Autowired
    private ICodeService codeService;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("示例3:加载codeMap中......");
        // 查询数据库数据
        List<String> codeList = codeService.listAll();
        for (int i = 0; i < codeList.size(); i++) {
            codeMap.put(i, codeList.get(i));
        }
    }
}

四、总结

1、CommandLineRunnerApplicationRunner调用的时机是在容器初始化完成之后,立即调用。

2、CommandLineRunnerApplicationRunner使用上没有区别,唯一区别是CommandLineRunner接受字符串数组参数,需要自行解析出健和值,ApplicationRunner的参数是ApplicationArguments,是对原始参数做了进一步的封装。

3、两个接口都可以使用 @Order 参数,支持工程启动后根据order 声明的权重值来决定调用的顺序(数字越小,优先级越高)。


本文首发于CSDN,为博主原创文章,如果需要转载,请注明出处,谢谢!


完结!

相关文章
|
XML 缓存 前端开发
Thymeleaf一篇就够了
Thymeleaf是Springboot官方支持的模板引擎,有着动静分离等独有特点,通过本文简单学习下吧!
64399 25
Thymeleaf一篇就够了
|
监控 Java
java多线程入门(六)Disruptor使用
java多线程入门(六)Disruptor使用
1183 0
|
8月前
|
供应链 JavaScript 前端开发
一个月内使用成品系统快速部署一套适合中小企业的ERP系统
本文介绍如何在一个月内快速部署适合中小企业的ERP系统,重点在于成品系统选型、核心业务流程标准化与模块化配置。方案涵盖系统架构、模块配置、极速上线流程、常见避坑指南及后续迭代建议,助力企业高效落地ERP系统。
245 0
|
Java UED
Java中String强转int:一种常见的错误和解决方法
在Java中将非数字字符串转换为整数会导致`NumberFormatException`。要解决这个问题,可以使用`try-catch`捕获异常,正则表达式验证数字格式,或利用异常信息提供错误提示。例如,`Integer.parseInt()`会因遇到非数字字符如`&quot;123abc&quot;`而抛出异常,但通过异常处理或正则`\\d+`可确保安全转换。记得在编程时避免直接强转,以防止程序异常中断。
|
前端开发 JavaScript 数据库
从零开始搭建创业公司全新技术栈解决方案
创业公司在初期面临的挑战之一就是如何构建一个既能满足当前需求,又能适应未来发展的技术栈。本文将全面探讨从后端到前端,再到云原生技术和AI大模型应用的各个层面,帮助创业者了解如何选择合适的开发语言、框架、工具,以及如何制定有效的开发流程,从而搭建一个强大而稳定的技术体系。
1210 1
从零开始搭建创业公司全新技术栈解决方案
|
传感器 物联网 微服务
Netty的源码分析和业务场景
【8月更文挑战第2天】Netty 是一款高性能的异步事件驱动网络框架,其源码深邃且复杂。通过采用Reactor模式与主从多线程设计,Netty能高效处理网络事件。例如,`NioEventLoop`负责I/O事件及任务执行,内置线程循环机制。内存管理方面,Netty提供高效内存池与`ByteBuf`类来减少开销并优化内存操作。在业务场景上,Netty广泛应用于分布式系统、微服务架构中的高效通信,以及实时通信场景如在线游戏和直播中的大量并发连接处理,同时也在物联网领域发挥重要作用,确保设备与服务器间稳定快速的数据传输。
302 1
|
NoSQL Java 数据库
【SpringBoot】简述springboot项目启动数据加载内存中的三种方法
【SpringBoot】简述springboot项目启动数据加载内存中的三种方法
633 0
|
XML 移动开发 数据格式
【Python】已解决:bs4.FeatureNotFound: Couldn’t find a tree builder with the features you requested: html5
【Python】已解决:bs4.FeatureNotFound: Couldn’t find a tree builder with the features you requested: html5
1188 1
|
存储 自然语言处理 数据库
UTF-8编码:打破字符编码的国界
UTF-8编码:打破字符编码的国界
|
图形学
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏14(附项目源码)
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏14(附项目源码)
269 3

热门文章

最新文章