小言_互联网的博客

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

349人阅读  评论(0)

一、前言

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

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

二、加载方式

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

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

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

注意事项

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

三、代码示例

3.1 使用@PostConstruct注解


   
  1. package com.example.demo.config;
  2. import com.example.demo.service.ICodeService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Component;
  5. import javax.annotation.PostConstruct;
  6. import javax.annotation.PreDestroy;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. @Component
  11. public class InitData1 {
  12. public static Map<Integer, String> codeMap = new HashMap<Integer, String>();
  13. @Autowired
  14. private ICodeService codeService;
  15. @PostConstruct
  16. public void init () {
  17. System.out.println( "示例1:加载codeMap中......");
  18. // 查询数据库数据
  19. List<String> codeList = codeService.listAll();
  20. for ( int i = 0; i < codeList.size(); i++) {
  21. codeMap.put(i, codeList.get(i));
  22. }
  23. }
  24. @PreDestroy
  25. public void destroy () {
  26. System.out.println( "系统启动成功,codeMap加载完成!");
  27. }
  28. }

3.2 CommandLineRunner接口


   
  1. package com.example.demo.config;
  2. import com.example.demo.service.ICodeService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.CommandLineRunner;
  5. import org.springframework.core.annotation.Order;
  6. import org.springframework.stereotype.Component;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. @Component
  11. @Order(1) // 初始化加载优先级,数字越小优先级越高
  12. public class InitData2 implements CommandLineRunner {
  13. public static Map<Integer, String> codeMap = new HashMap<Integer, String>();
  14. @Autowired
  15. private ICodeService codeService;
  16. @Override
  17. public void run (String... args) throws Exception {
  18. System.out.println( "示例2:加载codeMap中......");
  19. // 查询数据库数据
  20. List<String> codeList = codeService.listAll();
  21. for ( int i = 0; i < codeList.size(); i++) {
  22. codeMap.put(i, codeList.get(i));
  23. }
  24. }
  25. }

3.3 ApplicationRunner接口


   
  1. package com.example.demo.config;
  2. import com.example.demo.service.ICodeService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.ApplicationArguments;
  5. import org.springframework.boot.ApplicationRunner;
  6. import org.springframework.core.annotation.Order;
  7. import org.springframework.stereotype.Component;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import java.util.Map;
  11. @Component
  12. @Order(1) // 初始化加载优先级,数字越小优先级越高
  13. public class InitData3 implements ApplicationRunner {
  14. public static Map<Integer, String> codeMap = new HashMap<Integer, String>();
  15. @Autowired
  16. private ICodeService codeService;
  17. @Override
  18. public void run (ApplicationArguments args) throws Exception {
  19. System.out.println( "示例3:加载codeMap中......");
  20. // 查询数据库数据
  21. List<String> codeList = codeService.listAll();
  22. for ( int i = 0; i < codeList.size(); i++) {
  23. codeMap.put(i, codeList.get(i));
  24. }
  25. }
  26. }

四、总结

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

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

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

完结!


转载:https://blog.csdn.net/weixin_44299027/article/details/128973408
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场