本文介紹從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; }UserBeanInject.java
請註意:這裡的@ConfigurationProperties 註解裡面的 prefix 參數指的是在配置文件中你自己定義的標識符
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包裡面也是一種方法,但是要是被半路攔截,豈不是直接泄露數據,故不提倡,還有一點,就是代碼的可維護性會變得很低