写点什么

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

作者:No8g攻城狮
  • 2023-02-10
    河南
  • 本文字数:2127 字

    阅读完需:约 7 分钟

一、前言

一般来说,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;@Componentpublic 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,为博主原创文章,如果需要转载,请注明出处,谢谢!


完结!

发布于: 刚刚阅读数: 5
用户头像

No8g攻城狮

关注

熟了再告诉你 2022-12-03 加入

热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长

评论

发布
暂无评论
【SpringBoot】简述springboot项目启动数据加载内存中的三种方法_springboot_No8g攻城狮_InfoQ写作社区