摘要:中有兩個接口能實現該功能和。首先了解一下的基本用法,可以在系統啟動后執行里面的方法執行數據初始化如果有多個類的話也可以通過注解指定每個類的執行順序。
最近遇到一個功能點,數據庫中一張很簡單的表有一千多條數據,這里的數據主要做到了值域映射的作用,簡單來講就是我可以通過中文名拿到數據庫中對應的code值。原本的實現方式是每次用到之后去查一次sql,雖然不會有什么問題,但是只要是走了網絡io,都會消耗時間。所以這個方案需要想辦法優化。
優化的方式其實很簡單,數據量不多,一千多條數據放在內存里也占不了多少空間。因此完全可以把一次性把數據加載到內存中,后面只需要每次去內存里調用就可以了。
方案想好了就要想實現方式了,想個最直接的方案,在Spring容器初始化時就把這些數據從數據庫拿到內存中,后面就直接調用。
SpringBoot中有兩個接口能實現該功能:CommandLineRunner和ApplicationRunner。
首先了解一下CommandLineRunner的基本用法,CommandLineRunner可以在系統啟動后執行里面的run方法
@Componentpublic class DataPrepare implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("CommandLineRunner執行數據初始化"); }}
如果有多個類的話也可以通過@Order注解指定每個類的執行順序。
接著就可以寫代碼的實現了,首先定義一個類用來將Mysql的數據存到內存里,通過靜態的Map存儲
public class DataMap { public static Map<String, String> map = new HashMap<>(); public static void putData(String key, String value) { map.put(key, value); } public static String getDataByKey(String key) { return map.get(key); }}
接著在DataPrepare類中將數據都存入到靜態到Map中。
@Componentpublic class DataPrepare implements CommandLineRunner { @Autowired private DataMapper dataMapper; @Override public void run(String... args) throws Exception { //從數據庫中取數據 List<DataDO> dataDOS = dataMapper.selectList(Wrappers.emptyWrapper()); //寫入到DataMap中 dataDOS.forEach(item -> DataMap.putData(item.getName(), item.getCode())); }}
要使用到時候,只需要調用DataMap.getDataByKey()方法就可以直接使用了。
ApplicationRunner和CommandLineRunner的功能十分相似,實現方式也基本相同。同樣繼承接口,并實現接口的run方法。
@Componentpublic class ApplicationDataPrepare implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("ApplicationRunner執行數據初始化"); }}
在不指定@Order注解的情況下,ApplicationRunner會優先于CommandLineRunner執行。
兩者的區別:
CommandLineRunner和ApplicationRunner的功能幾乎是相同的,最大的區別在于兩者run方法中的入參有所不同,CommandLineRunner通過String數組
來接收啟動參數,而ApplicationRunner通過一個ApplicationArguments對象來接收。
在使用時,不管是String數組還是ApplicationArguments都可以拿到JVM的啟動參數。
為什么通過實現一個接口,重寫run方法就能達到啟動程序后就自動執行代碼的功能呢?我們可以通過SpringBoot的源碼去看:
點進SpringApplication.run()方法,一直進入到public ConfigurableApplicationContext run(String… args)方法中,在執行完一系列初始化方法之后,執行了this.callRunners(context, applicationArguments)方法
callRunners的方法比較簡單,首先定義了一個runners集合,并將需要執行的Bean放進去??梢钥吹紸pplicationRunner和CommandLineRunner在這里被放入了runners中,接著對Order注解進行排序,最后遍歷執行。
private void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList(); runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); AnnotationAwareOrderComparator.sort(runners); Iterator var4 = (new LinkedHashSet(runners)).iterator(); while(var4.hasNext()) { Object runner = var4.next(); if (runner instanceof ApplicationRunner) { this.callRunner((ApplicationRunner)runner, args); } if (runner instanceof CommandLineRunner) { this.callRunner((CommandLineRunner)runner, args); } }}
一個小小的細節可以節約多次的Sql調用。本章主要通過一個簡單的例子引出ApplicationRunner和CommandLineRunner,實際在使用時也可以通過懶加載,在第一次使用時將數據塞到靜態的Map里,也能實現類似緩存的效果。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/123719.html
摘要:文件服務器項目為文章共享社區,少不了的就是一個存儲文章的文件服務器,包括存儲一些圖片之類的靜態資源。例如數據庫的數據文件的配置文件和文件服務器目錄。 前言 這是一次完整的項目實踐,Angular頁面+Springboot接口+MySQL都通過Dockerfile打包成docker鏡像,通過docker-compose做統一編排。目的是實現整個項目產品的輕量級和靈活性,在將各個模塊的鏡像...
摘要:除了,還有十余種,有的是特定操作,比如轉儲內存日志有的是信息展示,比如顯示應用健康狀態。 showImg(http://ww1.sinaimg.cn/large/006tNc79gy1g5qb2coyfoj30u00k0tan.jpg); 前言 隨著線上應用逐步采用 SpringBoot 構建,SpringBoot應用實例越來多,當線上某個應用需要升級部署時,常常簡單粗暴地使用 kil...
摘要:熱加載代表的是我們不需要重啟服務器,就能夠類檢測得到,重新生成類的字節碼文件無論是熱部署或者是熱加載都是基于類加載器來完成的。驗證階段字節碼文件不會對造成危害準備階段是會賦初始值,并不是程序中的值。 一、SpringBoot入門 今天在慕課網中看見了Spring Boot這么一個教程,這個Spring Boot作為JavaWeb的學習者肯定至少會聽過,但我是不知道他是什么玩意。 只是大...
摘要:用戶態不能干擾內核態所以指令就有兩種特權指令和非特權指令不同的狀態對應不同的指令。非特權指令所有程序均可直接使用。用戶態常態目態執行非特權指令。 這是我今年從三月份開始,主要的大廠面試經過,有些企業面試的還沒來得及整理,可能有些沒有帶答案就發出來了,還請各位先思考如果是你怎么回答面試官?這篇文章會持續更新,請各位持續關注,希望對你有所幫助! 面試清單 平安產險 飛豬 上汽大通 浩鯨科...
Github 地址:https://github.com/Snailclimb/springboot-integration-examples ,歡迎各位 Star。 目錄: 使用 SpringBoot+Dubbo 搭建一個簡單分布式服務 實戰之前,先來看幾個重要的概念 什么是分布式? 什么是 Duboo? Dubbo 架構 什么是 RPC? 為什么要用 Dubbo? 開始實戰 1 ...
閱讀 1808·2021-11-23 09:51
閱讀 1267·2021-11-18 10:02
閱讀 962·2021-10-25 09:44
閱讀 2098·2019-08-26 18:36
閱讀 1619·2019-08-26 12:17
閱讀 1145·2019-08-26 11:59
閱讀 2746·2019-08-23 15:56
閱讀 3350·2019-08-23 15:05