springboot启动加载数据库数据到内存

1、概述

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

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

springbean初始化流程

st=>start: 开始
op1=>operation: Spring容器加载
op2=>operation: 调用构造函数
op3=>operation: @PostConstruct方法调用
op4=>operation: init()调用
op5=>operation: 其他代码
op6=>operation: destroy()调用
op7=>operation: @PreDestroy方法调用
e=>end: 结束

st->op1->op2->op3->op4->op5->op6->op7->e

2、加载方式

2.1、@PostConstruct注解

@PostConstruct注解修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的init()方法,被@PostConstruct注解修饰的方法会在构造函数之后,init()方法执行之前执行

被@PreDestroy注解修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法,被@PreDestroy注解修饰的方法会在destroy()方法之后、在Servlet被彻底卸载之前执行

@Component
@Slf4j
public class CacheDicUtils {
    private static Map<String, SysDictionary> dataMap = new HashMap<>();
    @Autowired
    private SysDictionaryMapper sysDictionaryMapper;
 
    @PostConstruct
    public void init() {
        QueryWrapper<SysDictionary> wrapper = new QueryWrapper<>();
 
        List<SysDictionary> list = sysDictionaryMapper.selectList(wrapper);
        for (SysDictionary sysDictionary : list) {
            dataMap.put(sysDictionary.getName(), sysDictionary);
          
        }
    }
 
    public static SysDictionary getDictDataByName(String name) {
        SysDictionary sysDictionary = dataMap.get(name);
        return sysDictionary ;
    }
}

2.2、@Order注解和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));
        }
    }
}

2.3、@Order注解和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));
        }
    }
}

2.4、static静态代码块

public class DicMap {
    @Autowired
    private static CustomerDao customerDao;
	
    private static HashMap<String,Dictionary> dataMap = new HashMap<>();
	
    static {
        // 在这里我们不能使用注入进来的customerDao,因为它此时还没有被创建出来,所以我们要在系统
        // 运行的时候获取项目的上下文手动去获取这个bean
        customerDao = SpringUtil.getBean(CustomerDao.class);
        queryDic();
    }
	
    // 把字典信息放到map中
    public static void queryDic(){
        List<Dictionary> dicList = customerDao.findAllDictionary();
		for(Dictionary dic : dicList){
			dataMap.put(dic.getKey,dic);
        }
    }
    // 获取字典信息的具体方法
    public static String getDicDataByKey(String key){
		Dictionary dictionary = dataMap.get(dataMap);
        return dictionary ;
	}

}

3、总结

相关推荐

  1. springboot启动数据库数据

    2024-01-12 19:04:05       64 阅读
  2. springboot启动热点数据Redis

    2024-01-12 19:04:05       56 阅读
  3. SpringBoot启动自己的策略类容器中使用?

    2024-01-12 19:04:05       116 阅读
  4. js预和滚动底部数据实现

    2024-01-12 19:04:05       48 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-12 19:04:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-12 19:04:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-12 19:04:05       87 阅读
  4. Python语言-面向对象

    2024-01-12 19:04:05       96 阅读

热门阅读

  1. Pytorch 反向传播 计算图被修改的报错

    2024-01-12 19:04:05       58 阅读
  2. go语言mysql的gorm基本用法

    2024-01-12 19:04:05       60 阅读
  3. 面试常见知识点--树的遍历

    2024-01-12 19:04:05       55 阅读
  4. Podman与Docker的区别

    2024-01-12 19:04:05       66 阅读
  5. Leetcod面试经典150题刷题记录 —— 二叉搜索树篇

    2024-01-12 19:04:05       56 阅读
  6. 【sklearn练习】鸢尾花

    2024-01-12 19:04:05       60 阅读
  7. Python中range数列与for循环

    2024-01-12 19:04:05       49 阅读
  8. StampedLock详解

    2024-01-12 19:04:05       49 阅读