SpringBoot项目启动数据加载内存的三种方法

目录
  • 一、前言
  • 二、加载方式
  • 三、代码示例
    • 3.1 使用@PostConstruct注解
    • 3.2 CommandLineRunner接口
    • 3.3 ApplicationRunner接口
  • 四、总结

    一、前言

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

    SpringBoot提供了两个接口: CommandLineRunner 和 ApplicationRunner 。实现其中接口,就可以在工程启动时将数据库中的数据加载到内存。使用的场景有:加载配置项到内存中;启动时将字典或白名单数据加载到内存(或缓存到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、CommandLineRunner和ApplicationRunner调用的时机是在容器初始化完成之后,立即调用。

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

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

    以上就是SpringBoot项目启动数据加载内存中的三种方法的详细内容,更多关于SpringBoot数据加载内存的资料请关注风君子博客其它相关文章!

    您可能感兴趣的文章:

    • SpringBoot使用Caffeine实现内存缓存示例详解
    • SpringBoot SpringSecurity 详细介绍(基于内存的验证)
    • SpringBoot基于过滤器和内存实现重复请求拦截功能
    • Springboot 如何设置启动内存
    • 指定springboot的jar运行内存方式

    Published by

    风君子

    独自遨游何稽首 揭天掀地慰生平