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