<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          不要重復造輪子?提高生產(chǎn)效率!3個常用的開源工具庫分享

          共 11462字,需瀏覽 23分鐘

           ·

          2020-09-17 00:14

          我們實際項目開發(fā)中是比較忌諱造輪子的,但是,自己在學習過程中造輪子絕對是對自己百利而無一害的!造輪子是一種特別能夠提高自己系統(tǒng)編程能力的手段。

          今天就分享幾個我常用的開源工具庫,希望對小伙伴們有幫助!

          1. OSHI[1] :一款為 Java 語言提供的基于 JNA 的(本機)操作系統(tǒng)和硬件信息庫。
          2. EasyExcel[2] :一款快速、簡單避免 OOM 的 java 處理 Excel 工具。
          3. Hutool[3] : 一個非常實用的 Java 工具類庫,對文件、流、加密解密、轉碼、正則、線程、XML 等 JDK 方法進行了封裝。

          以下是較為詳細一點的介紹,建議小伙伴們看完,方便自己快速上手,用在自己的項目中來提高生產(chǎn)效率。

          oshi

          介紹

          OSHI 是一款為 Java 語言提供的基于 JNA 的(本機)操作系統(tǒng)和硬件信息庫。

          JNA(Java Native Access)[4]是一個開源的 Java 框架,是 Sun 公司推出的一種調用本地方法的技術,是建立在經(jīng)典的 JNI 基礎之上的一個框架。之所以說它是 JNI 的替代者,是因為 JNA 大大簡化了調用本地方法的過程,使用很方便,基本上不需要脫離 Java 環(huán)境就可以完成。

          JNI(Java Native Interface) 是 JDK 提供的一個編程接口,它允許 Java 程序調用其他語言編寫的程序或者代碼庫,其實 JDK 本身的實現(xiàn)也大量用到 JNI 技術來調用本地 C 程序庫。

          通過 OSHI ,我們不需要安裝任何其他本機庫,就能查看內存和 CPU 使用率、磁盤和分區(qū)使用情況、設備、傳感器等信息。

          OSHI 旨在提供一種跨平臺的實現(xiàn)來檢索系統(tǒng)信息,支持 Windows、Linux、MacOS、Unix 等主流操作系統(tǒng)。

          官方是這樣介紹 oshi 的:(翻譯 Chrome 插件:Mate Translate):

          使用 oshi 你可以輕松制作出項目常用的系統(tǒng)監(jiān)控功能,如下圖所示:

          引入依賴

          Maven


          <dependency>
          ????<groupId>com.github.oshigroupId>
          ????<artifactId>oshi-coreartifactId>
          ????<version>5.2.5version>
          dependency>

          Gradle

          //?https://mvnrepository.com/artifact/com.github.oshi/oshi-core
          compile?group:?'com.github.oshi',?name:?'oshi-core',?version:?'5.2.5'

          功能演示

          獲取硬件信息對象HardwareAbstractionLayer

          //系統(tǒng)信息
          SystemInfo?si?=?new?SystemInfo();
          //操作系統(tǒng)信息
          OperatingSystem?os?=?si.getOperatingSystem();
          //硬件信息
          HardwareAbstractionLayer?hal?=?si.getHardware();

          有了代表硬件信息的對象HardwareAbstractionLayer 之后,我們就可以獲取硬件相關的信息了!

          下面簡單演示一下獲取內存和 CPU 相關信息。

          1.獲取內存相關信息

          //內存相關信息
          GlobalMemory?memory?=?hal.getMemory();
          //獲取內存總容量
          String?totalMemory?=?FormatUtil.formatBytes(memory.getTotal());
          //獲取可用內存的容量
          String?availableMemory?=?FormatUtil.formatBytes(memory.getAvailable());

          有了內存總容量和內存可用容量,你就可以計算出當前內存的利用率了。

          2.獲取 CPU 相關信息

          //CPU相關信息
          CentralProcessor?processor?=?hal.getProcessor();
          //獲取CPU名字
          String?processorName?=?processor.getProcessorIdentifier().getName();
          //獲取物理CPU數(shù)
          int?physicalPackageCount?=?processor.getPhysicalPackageCount();
          //獲取物理核心數(shù)
          int?physicalProcessorCount?=?processor.getPhysicalProcessorCount();

          EasyExcel

          介紹

          Java 解析、生成 Excel 常用的框架有 Apache poi、jxl ,但是這兩個框架使用起來都不夠優(yōu)雅,并且非常耗內存,嚴重時會導致內存溢出。

          怎么解決這個問題呢?

          推薦你使用阿里開源的 EasyExcel。正如這個項目官網(wǎng)介紹的那樣,這是一款快速、簡單避免 OOM 的 java 處理 Excel 工具。

          官方是這樣介紹 EasyExcel 的:

          引入依賴

          Maven


          <dependency>
          ????<groupId>com.alibabagroupId>
          ????<artifactId>easyexcelartifactId>
          ????<version>2.2.6version>
          dependency>

          Gradle

          //?https://mvnrepository.com/artifact/com.alibaba/easyexcel
          compile?group:?'com.alibaba',?name:?'easyexcel',?version:?'2.2.6'

          功能演示

          這里直接分享官方提供讀取 Excel 的例子(在實際項目中我對這部分做了簡單的封裝,涉及的地方比較多,就不分享出來了)。

          實體對象 (Excel 導入導出實體對象)

          @Data
          public?class?DemoData?{
          ????private?String?string;
          ????private?Date?date;
          ????private?Double?doubleData;
          }

          監(jiān)聽器 (自定義 AnalysisEventListener 一次讀取 5 條數(shù)據(jù)存儲到數(shù)據(jù)庫)

          //?有個很重要的點?DemoDataListener?不能被spring管理,要每次讀取excel都要new,然后里面用到spring可以構造方法傳進去
          public?class?DemoDataListener?extends?AnalysisEventListener<DemoData>?{
          ????private?static?final?Logger?LOGGER?=?LoggerFactory.getLogger(DemoDataListener.class);
          ????/**
          ?????*?每隔5條存儲數(shù)據(jù)庫,實際使用中可以3000條,然后清理list?,方便內存回收
          ?????*/

          ????private?static?final?int?BATCH_COUNT?=?5;
          ????List?list?=?new?ArrayList();
          ????/**
          ?????*?假設這個是一個DAO,當然有業(yè)務邏輯這個也可以是一個service。當然如果不用存儲這個對象沒用。
          ?????*/

          ????private?DemoDAO?demoDAO;
          ????public?DemoDataListener()?{
          ????????//?這里是demo,所以隨便new一個。實際使用如果到了spring,請使用下面的有參構造函數(shù)
          ????????demoDAO?=?new?DemoDAO();
          ????}
          ????/**
          ?????*?如果使用了spring,請使用這個構造方法。每次創(chuàng)建Listener的時候需要把spring管理的類傳進來
          ?????*
          ?????*?@param?demoDAO
          ?????*/

          ????public?DemoDataListener(DemoDAO?demoDAO)?{
          ????????this.demoDAO?=?demoDAO;
          ????}
          ????/**
          ?????*?這個每一條數(shù)據(jù)解析都會來調用
          ?????*
          ?????*?@param?data
          ?????*????????????one?row?value.?Is?is?same?as?{@link?AnalysisContext#readRowHolder()}
          ?????*?@param?context
          ?????*/

          ????@Override
          ????public?void?invoke(DemoData?data,?AnalysisContext?context)?{
          ????????LOGGER.info("解析到一條數(shù)據(jù):{}",?JSON.toJSONString(data));
          ????????list.add(data);
          ????????//?達到BATCH_COUNT了,需要去存儲一次數(shù)據(jù)庫,防止數(shù)據(jù)幾萬條數(shù)據(jù)在內存,容易OOM
          ????????if?(list.size()?>=?BATCH_COUNT)?{
          ????????????saveData();
          ????????????//?存儲完成清理?list
          ????????????list.clear();
          ????????}
          ????}
          ????/**
          ?????*?所有數(shù)據(jù)解析完成了?都會來調用
          ?????*
          ?????*?@param?context
          ?????*/

          ????@Override
          ????public?void?doAfterAllAnalysed(AnalysisContext?context)?{
          ????????//?這里也要保存數(shù)據(jù),確保最后遺留的數(shù)據(jù)也存儲到數(shù)據(jù)庫
          ????????saveData();
          ????????LOGGER.info("所有數(shù)據(jù)解析完成!");
          ????}
          ????/**
          ?????*?加上存儲數(shù)據(jù)庫
          ?????*/

          ????private?void?saveData()?{
          ????????LOGGER.info("{}條數(shù)據(jù),開始存儲數(shù)據(jù)庫!",?list.size());
          ????????demoDAO.save(list);
          ????????LOGGER.info("存儲數(shù)據(jù)庫成功!");
          ????}
          }

          持久層 (mybatis 或者 jpa 來做都行)

          /**
          ?*?假設這個是你的DAO存儲。當然還要這個類讓spring管理,當然你不用需要存儲,也不需要這個類。
          ?**/

          public?class?DemoDAO?{
          ????public?void?save(List?list)?{
          ????????//?如果是mybatis,盡量別直接調用多次insert,自己寫一個mapper里面新增一個方法batchInsert,所有數(shù)據(jù)一次性插入
          ????????System.out.println(list);
          ????}
          }

          讀取數(shù)據(jù)

          String?fileName?=?"src/test/resources/demo/demo.xlsx";
          //?這里?需要指定讀用哪個class去讀,然后讀取第一個sheet?文件流會自動關閉
          EasyExcel.read(fileName,?DemoData.class,?new?DemoDataListener()).sheet().doRead();

          輸出結果 (已過濾非必要數(shù)據(jù))

          2020-09-16?08:14:33.727?DEBUG?[main]?com.alibaba.excel.context.AnalysisContextImpl:91?-?Began?to?read:ReadSheetHolder{sheetNo=0, sheetName='Sheet1'}?com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder@6f3b5d16
          2020-09-16?08:14:33.870?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1577811661000,"doubleData":1.0,"string":"字符串0"}
          2020-09-16?08:14:33.870?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1577898061000,"doubleData":2.0,"string":"字符串1"}
          2020-09-16?08:14:33.871?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1577984461000,"doubleData":3.0,"string":"字符串2"}
          2020-09-16?08:14:33.871?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1578070861000,"doubleData":4.0,"string":"字符串3"}
          2020-09-16?08:14:33.872?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1578157261000,"doubleData":5.0,"string":"字符串4"}
          2020-09-16 08:14:33.872 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:80?- 5條數(shù)據(jù),開始存儲數(shù)據(jù)庫!
          [DemoData(string=字符串0,?date=Wed?Jan?01?01:01:01?CST?2020,?doubleData=1.0),?DemoData(string=字符串1,?date=Thu?Jan?02?01:01:01?CST?2020,?doubleData=2.0),?DemoData(string=字符串2,?date=Fri?Jan?03?01:01:01?CST?2020,?doubleData=3.0),?DemoData(string=字符串3,?date=Sat?Jan?04?01:01:01?CST?2020,?doubleData=4.0),?DemoData(string=字符串4,?date=Sun?Jan?05?01:01:01?CST?2020,?doubleData=5.0)]
          2020-09-16 08:14:33.874 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:82 -?存儲數(shù)據(jù)庫成功!
          2020-09-16?08:14:33.875?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1578243661000,"doubleData":6.0,"string":"字符串5"}
          2020-09-16?08:14:33.875?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1578330061000,"doubleData":7.0,"string":"字符串6"}
          2020-09-16?08:14:33.876?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1578416461000,"doubleData":8.0,"string":"字符串7"}
          2020-09-16?08:14:33.876?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1578502861000,"doubleData":9.0,"string":"字符串8"}
          2020-09-16?08:14:33.876?INFO?[main]?com.alibaba.easyexcel.test.demo.read.DemoDataListener:54?-?解析到一條數(shù)據(jù):{"date":1578589261000,"doubleData":10.0,"string":"字符串9"}
          2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:80?- 5條數(shù)據(jù),開始存儲數(shù)據(jù)庫!
          [DemoData(string=字符串5,?date=Mon?Jan?06?01:01:01?CST?2020,?doubleData=6.0),?DemoData(string=字符串6,?date=Tue?Jan?07?01:01:01?CST?2020,?doubleData=7.0),?DemoData(string=字符串7,?date=Wed?Jan?08?01:01:01?CST?2020,?doubleData=8.0),?DemoData(string=字符串8,?date=Thu?Jan?09?01:01:01?CST?2020,?doubleData=9.0),?DemoData(string=字符串9,?date=Fri?Jan?10?01:01:01?CST?2020,?doubleData=10.0)]
          2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:82 -?存儲數(shù)據(jù)庫成功!
          2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:80?-?0條數(shù)據(jù),開始存儲數(shù)據(jù)庫!
          []
          2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:82 -?存儲數(shù)據(jù)庫成功!
          2020-09-16 08:14:33.877 INFO [main] com.alibaba.easyexcel.test.demo.read.DemoDataListener:73 -?所有數(shù)據(jù)解析完成!

          Process?finished?with?exit?code?0

          Hutool

          介紹

          Hutool 是一個非常實用的 Java 工具類庫,對文件、流、加密解密、轉碼、正則、線程、XML 等 JDK 方法進行了封裝。

          非常使用的開源工具類庫,推薦小伙伴們在自己項目中使用。

          官方是這樣介紹 Hutool 的:

          引入依賴

          Maven


          <dependency>
          ????<groupId>cn.hutoolgroupId>
          ????<artifactId>hutool-allartifactId>
          ????<version>5.4.2version>
          dependency>

          Gradle

          //?https://mvnrepository.com/artifact/cn.hutool/hutool-all
          compile?group:?'cn.hutool',?name:?'hutool-all',?version:?'5.4.2'

          功能演示

          簡單演示幾個比較實用的功能。

          郵件

          在 Java 中發(fā)送郵件主要品依靠 javax.mail 包,但是由于使用比較繁瑣,因此 Hutool 針對其做了封裝。由于依賴第三方包,因此將此工具類歸類到 extra 模塊中。

          實際項目中可以自定義郵箱配置,然后讓配置保存在數(shù)據(jù)庫,并在緩存中保存一份。

          如果不想自定義配置的話,直接在配置文件中把郵箱配置寫死就行了。

          有了郵件的相關配置之后,定義郵件服務器之后即可發(fā)送郵件,非常方便:

          MailAccount?account?=?new?MailAccount();
          account.setHost("smtp.yeah.net");
          account.setPort("25");
          account.setAuth(true);
          account.setFrom("[email protected]");
          account.setUser("hutool");
          account.setPass("q1w2e3");

          MailUtil.send(account,?CollUtil.newArrayList("[email protected]"),?"測試",?"郵件來自Hutool測試",?false);

          唯一 ID

          在分布式環(huán)境中,唯一 ID 生成應用十分廣泛,生成方法也多種多樣,Hutool 針對一些常用生成策略做了簡單封裝。

          https://juejin.im/post/6844903935296176141

          Hutool 提供的唯一 ID 生成器的工具類,涵蓋了:

          • UUID
          • ObjectId(MongoDB)
          • Snowflake(Twitter)

          拿 UUID 舉例!

          Hutool 重寫java.util.UUID的邏輯,對應類為cn.hutool.core.lang.UUID,使生成不帶-的 UUID 字符串不再需要做字符替換,性能提升一倍左右

          //生成的UUID是帶-的字符串,類似于:a5c8a5e8-df2b-4706-bea4-08d0939410e3
          String?uuid?=?IdUtil.randomUUID();

          //生成的是不帶-的字符串,類似于:b17f24ff026d40949c85a24f4f375d42
          String?simpleUUID?=?IdUtil.simpleUUID();

          Http 請求工具類

          針對最為常用的 GET 和 POST 請求,HttpUtil 封裝了兩個方法,

          • HttpUtil.get
          • HttpUtil.post
          //?最簡單的HTTP請求,可以自動通過header等信息判斷編碼,不區(qū)分HTTP和HTTPS
          String?result1?=?HttpUtil.get("https://www.baidu.com");
          //?當無法識別頁面編碼的時候,可以自定義請求頁面的編碼
          String?result2?=?HttpUtil.get("https://www.baidu.com",?CharsetUtil.CHARSET_UTF_8);
          //可以單獨傳入http參數(shù),這樣參數(shù)會自動做URL編碼,拼接在URL中
          HashMap?paramMap?=?new?HashMap<>();
          paramMap.put("city",?"北京");
          String?result3?=?HttpUtil.get("https://www.baidu.com",?paramMap);

          緩存

          Hutool 提供了常見的幾種緩存策略的實現(xiàn):

          1. FIFO(first in first out) :先進先出策略。
          2. LFU(least frequently used) :最少使用率策略。
          3. LFU(least frequently used) :最少使用率策略。
          4. 定時緩存 :對被緩存的對象定義一個過期時間,當對象超過過期時間會被清理。
          5. ......

          FIFO(first in first out) 策略緩存使用:

          Cache?fifoCache?=?CacheUtil.newFIFOCache(3);

          //加入元素,每個元素可以設置其過期時長,DateUnit.SECOND.getMillis()代表每秒對應的毫秒數(shù),在此為3秒
          fifoCache.put("key1",?"value1",?DateUnit.SECOND.getMillis()?*?3);
          fifoCache.put("key2",?"value2",?DateUnit.SECOND.getMillis()?*?3);
          fifoCache.put("key3",?"value3",?DateUnit.SECOND.getMillis()?*?3);

          //由于緩存容量只有3,當加入第四個元素的時候,根據(jù)FIFO規(guī)則,最先放入的對象將被移除
          fifoCache.put("key4",?"value4",?DateUnit.SECOND.getMillis()?*?3);

          //value1為null
          String?value1?=?fifoCache.get("key1");

          控制臺打印封裝-Console

          一般情況下,我們打印信息到控制臺小伙伴們應該再熟悉不過了!

          System.out.println("Hello?World");

          但是,這種方式不滿足很多場景的需要:

          1. 不支持參數(shù),對象打印需要拼接字符串
          2. 不能直接打印數(shù)組,需要手動調用Arrays.toString

          為此,Hutool 封裝了Console對象。

          Console 對象的使用更加類似于 Javascript 的console.log()方法,這也是借鑒了 JS 的一個語法糖。

          String[]?a?=?{"java",?"c++",?"c"};
          Console.log(a);//控制臺輸出:[java, c++, c]

          Console.log("This?is?Console?log?for?{}.",?"test");//控制臺輸出:This is Console log for test.

          參考資料

          [1]

          oshi: https://github.com/oshi/oshi

          [2]

          EasyExcel: https://github.com/alibaba/easyexcel

          [3]

          Hutool: https://github.com/looly/hutool

          [4]

          JNA(Java Native Access): https://github.com/java-native-access/jna

          閑聊

          其實今天本來是準備更新一篇系統(tǒng)設計面試指南的,畢竟系統(tǒng)設計幾乎也是面試必問了,非常重要。?最近詢問這方面問題的小伙伴比較多。

          文章大概要寫啥內容都構思好了,結果還是過于天真。因為涉及到的內容和知識點太多了。預計會在下周分享(如果中途沒出啥狀況的話)。

          另外,上周日和我們大學的傳奇人物,研究生在華科,目前在華為的學長聊了一會。收獲確實不少,果然優(yōu)秀的人總有一些過人的地方(這周六應該會把自己的所得所獲分享出來)。

          最近更新的一些好文章推薦:


          往期推薦



          國博史上首次收藏代碼!代碼的 URL 設計還沒遵循RESTful API 風格?

          你見過最爛的Java代碼長什么樣子?

          我利用業(yè)余時間通過技術寫作掙了3個頂配Mac Pro

          被噴了?聊聊我開源RPC框架的那些事

          6k+點贊的SpringBoot+Netty分布式即時通訊系統(tǒng)!愛了愛了!

          好一個 Spring Boot 開源在線考試系統(tǒng)!解決了我的燃眉之急


          我整理的4本PDF文檔,公眾號“后端技術進階”后臺回復“面試突擊”即可免費獲取。

          文章有幫助可以點個「在看」或「分享」,都是支持,我都喜歡!

          我是Guide哥,Java后端開發(fā),會一點前端知識,喜歡烹飪,自由的少年。一個三觀比主角還正的技術人。我們下期再見!

          瀏覽 46
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  新超碰97| 人妻蜜桃| 亚洲黄色视频网站免费在线观看 | 日本无码性爱 | 欧美视频色 |