關於自定義程式打包成jar包,並讀取配置

来源:https://www.cnblogs.com/XuZiYan/archive/2023/07/31/17593818.html
-Advertisement-
Play Games

本文介紹從gitee下載nacos源碼,在本地編譯,並導入idea進行本地調試。 # 從gitee下載源碼 由於github訪問速度慢,所以我選擇使用gitee的鏡像倉庫: ```shell git clone https://gitee.com/mirrors/Nacos.git ``` 本文使用 ...


前言

在實際開發過程中,我們有時候有把你編寫的一段程式打成jar包的需求,而一些配置是需要去配置文件裡面讀取關於這項目的一些配置,本人在網路上查詢了眾多的資料,總的來說可以歸為3類

1.從資料庫讀取配置

   老生常談,在dao層從資料庫獲取配置信息,然後返回到Service層進行業務邏輯處理

2.在每次調用這個jar的時候通過關鍵字去讀取配置

  在這一類中,方法有很多,不過大體都是

InputStream ins = getClass().getResourceAsStream("/resource/dbconfig.properties");

  通過IO流對配置文件進行讀取,然後再從 InputStream 流中讀取數據,沒什麼技術含量,便不多講

例如以下例子,就是通過Properties流來讀取配置 

 /**
     * 讀取配置文件屬性
     * @param path  配置文件路徑
     * @return
     * @throws IOException
     */
    public Map readerConfigurationFile(String path) throws IOException {
        /**
         * 使用Properties讀取配置文件並獲取配置信息
         */
        Properties properties = new Properties();
        InputStream input = new BufferedInputStream(new FileInputStream(path));
        properties.load(input);

        /**
         * 將獲取到的配置信息轉存到map集合
         */
        Map map = new HashMap();
        for (Object key : properties.keySet()) {
            if (properties.get(key) != null && !properties.get(key).toString().trim().equals("")){
                map.put(key,properties.get(key));
            }
        }
        return map;
    }

 

3.通過Spring 自動裝配,在項目啟動時就把配置信息發送到jar包裡面(強烈推薦)

  這個方法雖然前期建立的時候比較繁瑣,但是完成之後簡直方便到飛起

  首先,建立一下格式的結構,方便我們後面能夠快捷找到要編寫的文件

實際上DemoApplication.java 是可以去掉的,只是個人為了方便測試寫的代碼,看是否有bug就留下來啟動項目用的

 最最最重要的pom.xml文件應該這樣寫:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-->--------------------這裡是自己jar的情況,自己編寫---------  -------<-->
<modelVersion>4.0.0</modelVersion> <groupId>com.transfer</groupId> <artifactId>DataTransferService</artifactId> <version>0.0.1-SNAPSHOT</version> <name>DataTransferService</name> <description>DataTransferService</description> <properties> <spring-boot.version>2.6.13</spring-boot.version> </properties>
<!-->---------------------------------------------------------------<-->
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 自動配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <!-- 配置屬性 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional><!-- 依賴不傳遞 --> </dependency> <!--Lombok依賴--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <!--mysql資料庫驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> <scope>runtime</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> </build> </project>

 

  在config包裡面,我們要建立幾個配置文件:

UserConfiguration.java

@Slf4j
@Configuration
@ConditionalOnExpression("${enabled:true}")
@EnableConfigurationProperties(UserConfiguration .class)
public class UserConfiguration {

    @Bean
    @Primary
    public UserConfig getConfigValue(UserProperties properties){
        if (properties.getLog()){
            log.info("資料庫中轉服務API組件 ——> 開啟組件");
        }
        return new UserConfig()
                .setOtherDataSourcesMap(properties.getOtherDataSourcesMap())
                .setLog(properties.getLog());
    }
}

UserConfig.java

@Data
@Accessors(chain = true)
public class UserConfig implements Serializable {
    private Map<String,Map<String,Map<String,Object>>> otherDataSourcesMap;

    /** 是否列印操作日誌 */
    private Boolean log = true;
}
UserProperties.java
@Data
@ConfigurationProperties(prefix = "User")
public class UserProperties implements Serializable {

    private Map<String,Map<String,Map<String,Object>>> otherDataSourcesMap;

    /** 是否開啟 */
    boolean enabled = true;

    /** 是否列印操作日誌 */
    private Boolean log = false;
}
請註意:這裡的@ConfigurationProperties 註解裡面的 prefix 參數指的是在配置文件中你自己定義的標識符
UserBeanInject.java
public class UserBeanInject {

    /**
     * 註入配置Bean
     *
     * @param config 配置對象
     */
    @Autowired(required = false)
    public void setConfig(UserConfig config){
        UserSpi.setConfig(config);
    }
}

 當然,還有重要的一步,那就是在resources文件夾下創建一個Spring自動裝配的約定文件,使得我們這幾個java配置文件能夠生效

 spring.factories

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  自己定義的包路徑.configuration.UserConfiguration, \
  自己定義的包路徑.configuration.UserBeanInject

 然後,我們要暴露這個介面

UserSpi.Java
@Slf4j
public class UserSpi{
    public volatile static UserConfig config;

    public static void setConfig(UserConfig config){
        UserSpi.config = config;
        if (config.getLog()){
            log.info("資料庫中轉服務API組件 ——> 列印配置信息\n", JSONUtil.toJsonStr(UserSpi.config));
        }
    }

    // =================== 獲取Api 相關 ===================

    public static IUserService api = new UserServiceImpl();
}

這樣基本上完成jar自動裝配外部配置文件的配置,業務邏輯什麼的看個人習慣自己去編寫

 

感言

  • 從資料庫裡面讀取配置信息方便時挺方便的,但是在高併發與高請求的項目中並不適用,而每次調用這個jar的時候通過關鍵字去讀取配置會造成記憶體資源不斷被刷新,容易記憶體爆炸,個人推薦第3種方式。
  • 還有,每次該改寫完代碼,一定要重新構建項目,重新編譯一下,不然你打出來的Jar包,永遠都是你改寫之前的代碼,改寫之後的代碼不會寫入到Jar包裡面!!!!
  • 對了,直接把配置文件裡面的值直接傳遞到jar包裡面也是一種方法,但是要是被半路攔截,豈不是直接泄露數據,故不提倡,還有一點,就是代碼的可維護性會變得很低

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • DDD領域建模被各個大小廠商提起並應用,而每個人都有自己的理解,本文就是針對小白,系統地講解DDD到底是什麼,解決了什麼問題,及一些建議和實踐。本文主要是思想的一種碰撞和分享,希望能對朋友們有所啟發或幫助。 ...
  • 環境:CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 sipp版本:3.6.1 python版本:3.9.12 日常工作中,有時會遇到批量自動壓測FreeSWITCH的需求,sipp是一個非常好的VoIP壓測工具,python是個很好用的腳本語言,今天記錄下CentOS 7環 ...
  • ## Spring安全框架 Spring Security是一個用於保護基於Java的應用程式的框架。它是一個功能強大且高度可定製的身份驗證和訪問控制框架,可以輕鬆地集成到各種應用程式中,包括Web應用程式和RESTful Web服務。Spring Security提供了全面的安全解決方案,用於身份 ...
  • 前言:今天在解決一個問題時,程式總是不能輸出正確值,分析邏輯思路沒問題後,發現原來是由於函數傳遞導致了這個情況。 LeetCode 113 問題:給你二叉樹的根節點root和一個整數目標和targetSum,找出所有 從根節點到葉子節點 路徑總和等於給定目標和的路徑。 示例 輸入:root = [5 ...
  • ## python規範 - 函數必須寫註釋:文檔註釋格式`'''註釋內容'''` - 參數中的等號兩邊不要用空格 - 相鄰函數用兩個空行隔開 - 小寫 \+ 下劃線 1. 函數名 2. 模塊名 3. 實例名 - 駝峰法 1. 類名 ## tips ```python # 一行代碼太長,使用\折行 i ...
  • # 資料庫連接池 ## **傳統獲取Connection問題分析** 1. 傳統的JDBC資料庫使用 DriverManager 來獲取, **每次向資料庫建立連接的時候都要將 Connection 載入到記憶體中,再驗證IP地址,用戶名和密碼(0.05 ~ 1 s 時間)**。需要資料庫連接的時候, ...
  • ### 一.定義 面向對象是:將事務高度抽象化的編程模式 將問題分解成一個個小步驟,對每個步驟進行抽象,形成對象,通過不同的對象之間調用,組合解決問題。 在進行面向對象進行編程時,要把屬性、行為等封裝成對象,然後基於這些對象及對象的能力進行業務邏輯的實現。創建一次,重覆使用 ### 二.面向對象三個 ...
  • ##### RabbitMQ安裝 ``` docker run -d --name xd_rabbit -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 rabbi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...