Apache?Commons?Config管理配置文件核心功能使用
第1章:引言
咱們都知道,在軟件開發(fā)中,管理配置文件是一件既重要又讓人頭疼的事。想象一下,咱們的應(yīng)用程序有一堆設(shè)置需要調(diào)整,比如數(shù)據(jù)庫的連接信息、應(yīng)用的端口號,或者是一些功能的開關(guān)。如果這些信息硬編碼在代碼里,每次改動都要重新編譯整個(gè)程序,那豈不是太麻煩了?這時(shí)候,配置文件就派上用場了。它允許咱們在不修改代碼的情況下,靈活地調(diào)整這些設(shè)置。
Apache Commons Config,正是這樣一個(gè)強(qiáng)大的工具,它幫助Java開發(fā)者輕松管理應(yīng)用配置。使用它,咱們可以優(yōu)雅地加載、讀取、寫入和監(jiān)控配置文件。不僅如此,它支持多種格式的配置文件,比如XML、Properties、JSON等,非常方便。小黑在這里就要給咱們詳細(xì)介紹一下這個(gè)工具的魅力所在。
第2章:Apache Commons Config簡介
介紹一下Apache Commons Config是什么。它是Apache軟件基金會提供的一個(gè)開源Java庫,專門用于處理應(yīng)用程序的配置。這個(gè)庫不僅可以幫咱們處理不同格式的配置文件,還可以讓咱們以統(tǒng)一的方式訪問這些配置信息。這意味著不管配置信息是存儲在Properties文件、XML文件還是數(shù)據(jù)庫中,咱們都可以用相同的方式來獲取這些信息。夠聰明的,對吧?
來舉個(gè)例子。假設(shè)咱們有一個(gè)Properties格式的配置文件,內(nèi)容大概是這樣的:
# application.properties database.url=jdbc:mysql://localhost:3306/mydb database.user=root database.password=123456
這是一個(gè)標(biāo)準(zhǔn)的數(shù)據(jù)庫連接配置。使用Apache Commons Config,小黑可以輕松地讀取這些信息??纯聪旅孢@段代碼:
import org.apache.commons.configuration2.Configuration; import org.apache.commons.configuration2.builder.fluent.Configurations; public class AppConfig { public static void main(String[] args) { Configurations configs = new Configurations(); try { Configuration config = configs.properties("application.properties"); String dbUrl = config.getString("database.url"); String dbUser = config.getString("database.user"); String dbPassword = config.getString("database.password"); System.out.println("數(shù)據(jù)庫URL: " + dbUrl); System.out.println("用戶名: " + dbUser); System.out.println("密碼: " + dbPassword); } catch (Exception e) { e.printStackTrace(); } } }
在這段代碼中,小黑首先導(dǎo)入了必要的Apache Commons Config類。然后,創(chuàng)建了一個(gè)Configurations
對象,它是配置操作的起點(diǎn)。通過調(diào)用configs.properties()
方法,小黑加載了那個(gè)Properties文件。隨后,就可以使用getString()
方法來獲取配置項(xiàng)的值了。
這樣做的好處是顯而易見的。咱們的配置信息變得更加靈活和動態(tài),不需要重新編譯代碼就可以隨時(shí)調(diào)整配置。而且,如果咱們的應(yīng)用程序需要支持多種格式的配置文件,Apache Commons Config也能輕松應(yīng)對。
第3章:安裝和配置
添加Maven依賴
在項(xiàng)目的pom.xml
文件中,咱們需要添加Apache Commons Config的依賴。像這樣:
<dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-configuration2</artifactId> <version>2.7</version> <!-- 這里的版本號根據(jù)最新版自行調(diào)整 --> </dependency> </dependencies>
加入這段代碼后,Maven會在構(gòu)建項(xiàng)目時(shí)自動下載和引入Apache Commons Config。咱們就不用操心手動管理庫文件了。
基本配置文件
接下來,小黑來講講如何創(chuàng)建一個(gè)基本的配置文件。假設(shè)咱們正在開發(fā)一個(gè)Web應(yīng)用,需要配置一些數(shù)據(jù)庫連接的信息。咱們可以創(chuàng)建一個(gè)名為database.properties
的文件,內(nèi)容大概是這樣的:
# database.properties database.url=jdbc:mysql://localhost:3306/myapp database.user=admin database.password=secret
這個(gè)文件包含了連接數(shù)據(jù)庫所需的基本信息:URL、用戶名和密碼。
加載配置文件
現(xiàn)在,咱們來看看如何在Java代碼中加載這個(gè)配置文件。小黑先寫個(gè)簡單的類來演示:
import org.apache.commons.configuration2.Configuration; import org.apache.commons.configuration2.builder.fluent.Configurations; public class DatabaseConfig { public static void main(String[] args) { Configurations configs = new Configurations(); try { // 加載配置文件 Configuration config = configs.properties("database.properties"); // 讀取配置信息 String dbUrl = config.getString("database.url"); String dbUser = config.getString("database.user"); String dbPassword = config.getString("database.password"); // 輸出配置信息 System.out.println("數(shù)據(jù)庫URL: " + dbUrl); System.out.println("數(shù)據(jù)庫用戶名: " + dbUser); System.out.println("數(shù)據(jù)庫密碼: " + dbPassword); } catch (Exception e) { e.printStackTrace(); } } }
這段代碼展示了如何使用Apache Commons Config來讀取配置文件。咱們首先創(chuàng)建了一個(gè)Configurations
對象,這是操作配置文件的起點(diǎn)。通過調(diào)用configs.properties()
方法,咱們加載了剛才創(chuàng)建的database.properties
文件。然后,就可以用getString()
方法讀取各項(xiàng)配置了。
第4章:核心功能解析
配置文件格式支持
Apache Commons Config支持多種格式的配置文件,比如Properties、XML、JSON等。這意味著咱們可以根據(jù)項(xiàng)目的需求靈活選擇配置文件的格式。比如說,如果咱們需要一個(gè)XML格式的配置文件,可以這樣寫:
<!-- database.xml --> <configuration> <property name="database.url">jdbc:mysql://localhost:3306/myapp</property> <property name="database.user">admin</property> <property name="database.password">secret</property> </configuration>
然后在Java代碼中這樣加載它:
Configuration xmlConfig = configs.xml("database.xml"); String dbUrl = xmlConfig.getString("database.url"); // 其他操作與之前類似
基本讀取操作
讀取配置文件中的值是Apache Commons Config的基本功能。咱們不僅可以讀取字符串類型的數(shù)據(jù),還可以直接讀取其他類型,比如整數(shù)、布爾值等。比如:
// 假設(shè)配置文件中有這樣的項(xiàng) // app.timeout=30 // app.featureEnabled=true int timeout = config.getInt("app.timeout"); boolean isFeatureEnabled = config.getBoolean("app.featureEnabled"); System.out.println("超時(shí)時(shí)間: " + timeout); System.out.println("功能是否啟用: " + isFeatureEnabled);
數(shù)據(jù)類型轉(zhuǎn)換
Apache Commons Config還提供了數(shù)據(jù)類型轉(zhuǎn)換的功能。這意味著即使配置值是以字符串的形式存儲的,咱們也可以輕松地將其轉(zhuǎn)換為其他類型。這個(gè)功能在處理數(shù)字、布爾值等類型的配置項(xiàng)時(shí)特別有用。
寫入和保存配置
除了讀取配置,Apache Commons Config還允許咱們寫入或修改配置項(xiàng),并將更改保存到文件中。這在需要動態(tài)更新配置時(shí)非常有用??纯聪旅娴睦樱?/p>
FileBasedConfigurationBuilder<FileBasedConfiguration> builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class) .configure(new Parameters().properties().setFileName("database.properties")); Configuration config = builder.getConfiguration(); // 修改配置 config.setProperty("database.user", "newUser"); config.setProperty("database.password", "newPassword"); // 保存更改 builder.save();
這段代碼展示了如何修改配置文件中的值并保存這些更改。咱們首先創(chuàng)建了一個(gè)FileBasedConfigurationBuilder
對象,指定了配置文件的類型和位置。然后,獲取配置對象,修改配置項(xiàng),并通過調(diào)用builder.save()
來保存更改。
第5章:高級特性
層次化配置
在大型項(xiàng)目中,配置可能會變得非常復(fù)雜。咱們可能需要根據(jù)不同的環(huán)境(開發(fā)、測試、生產(chǎn))加載不同的配置文件。Apache Commons Config提供了層次化配置的功能,使得這種情況更容易處理。比如說,咱們可以有一個(gè)基礎(chǔ)的配置文件,然后根據(jù)不同環(huán)境疊加額外的配置。
看看下面的代碼:
Configurations configs = new Configurations(); // 加載基礎(chǔ)配置 Configuration config = configs.properties("base.properties"); // 根據(jù)環(huán)境變量加載額外的配置 String env = System.getenv("APP_ENV"); if ("development".equals(env)) { config = configs.properties("dev.properties"); } else if ("production".equals(env)) { config = configs.properties("prod.properties"); } // 使用合并的配置 String dbUrl = config.getString("database.url"); // 其他操作
這段代碼首先加載了一個(gè)基礎(chǔ)配置文件,然后根據(jù)應(yīng)用的運(yùn)行環(huán)境加載額外的配置文件。這種方式可以讓咱們的配置更加靈活和模塊化。
組合配置
有時(shí)候,咱們可能需要從多個(gè)配置源中讀取配置。Apache Commons Config允許咱們創(chuàng)建一個(gè)組合配置,這個(gè)配置可以包含多個(gè)單獨(dú)的配置對象。例如,咱們可能有一個(gè)默認(rèn)的配置文件,再加上用戶自定義的配置文件。咱們可以這樣做:
CompositeConfiguration compositeConfig = new CompositeConfiguration(); compositeConfig.addConfiguration(new PropertiesConfiguration("user.properties")); compositeConfig.addConfiguration(new PropertiesConfiguration("default.properties")); String dbUrl = compositeConfig.getString("database.url"); // 其他操作
在這個(gè)例子中,CompositeConfiguration
對象首先嘗試從user.properties
中讀取配置,如果找不到,再從default.properties
中讀取。
動態(tài)配置更新
在某些應(yīng)用場景中,咱們可能需要在運(yùn)行時(shí)動態(tài)更新配置。Apache Commons Config支持這一功能。通過使用文件監(jiān)控機(jī)制,咱們可以在配置文件發(fā)生變化時(shí)自動重新加載配置。這樣,應(yīng)用程序可以響應(yīng)配置的變化,而無需重啟。
看看如何實(shí)現(xiàn)這個(gè)功能:
FileBasedConfigurationBuilder<FileBasedConfiguration> builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class) .configure(new Parameters().properties().setFileName("config.properties")); PeriodicReloadingTrigger trigger = new PeriodicReloadingTrigger(builder.getReloadingController(), null, 1, TimeUnit.MINUTES); trigger.start(); // 在應(yīng)用程序的其他部分使用 builder.getConfiguration() 獲取最新配置
在這個(gè)例子中,小黑創(chuàng)建了一個(gè)PeriodicReloadingTrigger
,它會定期檢查配置文件是否有更新。如果有,它會自動重新加載配置。
第6章:實(shí)戰(zhàn)案例
案例1:配置動態(tài)加載
想象一下,咱們正在開發(fā)一個(gè)Web應(yīng)用,需要根據(jù)不同的部署環(huán)境加載相應(yīng)的數(shù)據(jù)庫配置。這時(shí),動態(tài)加載配置文件就顯得尤為重要了。比如,咱們可以根據(jù)環(huán)境變量來確定加載哪個(gè)配置文件。
public class DynamicConfigLoader { public static void main(String[] args) { String environment = System.getenv("APP_ENV"); Configurations configs = new Configurations(); try { Configuration config; if ("production".equals(environment)) { config = configs.properties("config-prod.properties"); } else { config = configs.properties("config-dev.properties"); } // 使用配置 String dbUrl = config.getString("database.url"); System.out.println("數(shù)據(jù)庫URL: " + dbUrl); } catch (ConfigurationException e) { e.printStackTrace(); } } }
在這個(gè)例子中,根據(jù)APP_ENV
環(huán)境變量的值,程序決定是加載生產(chǎn)環(huán)境的配置文件config-prod.properties
,還是開發(fā)環(huán)境的config-dev.properties
。
案例2:配置變更通知
另一個(gè)常見的需求是在配置文件更改時(shí)自動更新應(yīng)用程序中的配置。這在需要熱更新配置的系統(tǒng)中尤其重要??纯聪旅孢@個(gè)例子:
public class ConfigChangeNotifier { public static void main(String[] args) { FileBasedConfigurationBuilder<FileBasedConfiguration> builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class) .configure(new Parameters().properties().setFileName("config.properties")); ReloadingController reloadingController = builder.getReloadingController(); reloadingController.addEventListener(ReloadingEvent.ANY, event -> { try { Configuration config = builder.getConfiguration(); // 處理配置變更 String newValue = config.getString("some.config.key"); System.out.println("配置已更新: " + newValue); } catch (ConfigurationException e) { e.printStackTrace(); } }); // 啟動自動重載 new PeriodicReloadingTrigger(reloadingController, null, 1, TimeUnit.MINUTES).start(); } }
這里,小黑使用了ReloadingController
來監(jiān)聽配置文件的變更。一旦檢測到文件有變化,程序就會重新加載配置,并執(zhí)行相應(yīng)的更新操作。
案例3:組合不同來源的配置
在一些復(fù)雜的項(xiàng)目中,咱們可能需要從多個(gè)來源獲取配置信息。例如,一部分配置存儲在文件中,另一部分可能來自環(huán)境變量或者數(shù)據(jù)庫。Apache Commons Config可以輕松處理這種情況。
public class CombinedConfigExample { public static void main(String[] args) { Configurations configs = new Configurations(); try { Configuration fileConfig = configs.properties("config.properties"); EnvironmentConfiguration envConfig = new EnvironmentConfiguration(); CompositeConfiguration compositeConfig = new CompositeConfiguration(); compositeConfig.addConfiguration(fileConfig); compositeConfig.addConfiguration(envConfig); // 使用組合配置 String dbUrl = compositeConfig.getString("database.url"); String someEnvVar = compositeConfig.getString("SOME_ENV_VAR"); System.out.println("數(shù)據(jù)庫URL: " + dbUrl); System.out.println("環(huán)境變量值: " + someEnvVar); } catch (ConfigurationException e) { e.printStackTrace(); } } }
在這個(gè)例子中,小黑創(chuàng)建了一個(gè)CompositeConfiguration
對象,它包含了從文件和環(huán)境變量中讀取的配置。這樣,咱們就可以在一個(gè)地方統(tǒng)一管理所有的配置信息了。
第7章:最佳實(shí)踐
1. 保持配置文件簡潔明了
在編寫配置文件時(shí),清晰和簡潔至關(guān)重要。避免使用模糊不清的鍵名或過于復(fù)雜的結(jié)構(gòu)。例如,如果咱們在處理數(shù)據(jù)庫相關(guān)的配置,最好是這樣命名:
# Good database.url=jdbc:mysql://localhost:3306/mydb database.user=root database.password=123456 # Not so good dbConnection=jdbc:mysql://localhost:3306/mydb userForDatabase=root pass=123456
在第一種情況下,每個(gè)配置項(xiàng)的含義一目了然,而第二種則不那么直觀。
2. 避免硬編碼
盡量避免在代碼中硬編碼配置值。這樣做的問題在于,一旦需要更改配置,就必須重新編譯和部署應(yīng)用。使用Apache Commons Config,咱們可以輕松從外部文件加載配置,使得應(yīng)用更加靈活。
3. 處理異常情況
讀取配置文件時(shí)可能會遇到各種異常,例如文件不存在、格式錯誤等。咱們應(yīng)該妥善處理這些異常,避免應(yīng)用在啟動或運(yùn)行時(shí)崩潰。
try { Configuration config = configs.properties("config.properties"); // 使用配置 } catch (ConfigurationException e) { // 異常處理邏輯 e.printStackTrace(); }
4. 安全地處理敏感信息
如果配置文件中包含敏感信息(如數(shù)據(jù)庫密碼),考慮使用加密或其他機(jī)制來保護(hù)這些數(shù)據(jù)。不應(yīng)該直接以明文形式存儲在配置文件中。
5. 使用類型安全的讀取方法
Apache Commons Config提供了多種讀取配置值的方法。使用類型安全的方法可以減少運(yùn)行時(shí)錯誤。例如,使用getInt()
、getBoolean()
等方法,而不是將所有值都作為字符串讀取。
6. 利用環(huán)境變量和系統(tǒng)屬性
在某些情況下,咱們可以利用環(huán)境變量或系統(tǒng)屬性來覆蓋配置文件中的值。這在多環(huán)境部署時(shí)特別有用,比如開發(fā)環(huán)境和生產(chǎn)環(huán)境。
String dbUrl = config.getString("database.url", System.getenv("DB_URL"));
在這里,如果環(huán)境變量DB_URL
被設(shè)置,它將覆蓋配置文件中的database.url
值。
7. 定期復(fù)查和更新配置文件
隨著應(yīng)用的發(fā)展,配置需求可能會發(fā)生變化。定期復(fù)查和更新配置文件,確保它們?nèi)匀环袭?dāng)前的需求。
8. 使用版本控制
將配置文件放在版本控制系統(tǒng)中,這樣可以跟蹤歷史更改,也便于在出現(xiàn)問題時(shí)回滾到早期版本。
9. 文檔化配置項(xiàng)
對于復(fù)雜的配置文件,編寫相關(guān)文檔說明每個(gè)配置項(xiàng)的作用和預(yù)期值是非常有幫助的。這對于新加入項(xiàng)目的開發(fā)者來說尤其重要。
第8章:性能和限制
性能考慮
首先,咱們來談?wù)勑阅?。通常情況下,Apache Commons Config的性能對大多數(shù)應(yīng)用來說是足夠的。它在讀取和解析配置文件時(shí)是相當(dāng)高效的,特別是對于那些只在應(yīng)用啟動時(shí)加載一次配置的場景。但是,如果咱們需要頻繁地讀取或重新加載配置,那就得考慮一下性能的影響了。
例如,如果咱們的應(yīng)用程序依賴于實(shí)時(shí)更新的配置數(shù)據(jù),頻繁地檢查和重新加載配置文件可能會影響性能。這種情況下,咱們可能需要考慮緩存機(jī)制,或者是優(yōu)化配置文件的結(jié)構(gòu),以減少不必要的性能開銷。
// 示例:使用緩存來優(yōu)化性能 Configuration config = new CachingConfiguration(configs.properties("config.properties"));
在這個(gè)例子中,CachingConfiguration
提供了一個(gè)簡單的緩存機(jī)制,可以減少頻繁讀取配置文件所帶來的開銷。
限制和局限性
接下來,談?wù)勏拗坪途窒扌?。雖然Apache Commons Config是一個(gè)功能強(qiáng)大的庫,但它也有一些限制。比如,它并不支持所有可能的配置文件格式。雖然常見的格式如Properties、XML和JSON都得到了支持,但對于一些更特殊的格式,比如YAML,就需要另外尋找解決方案了。
此外,Apache Commons Config在處理非常大的配置文件時(shí)可能會遇到性能問題。如果配置文件的大小超過了常規(guī)范圍,解析和加載這些文件可能會消耗相當(dāng)多的時(shí)間和內(nèi)存資源。這種情況下,咱們可能需要考慮拆分配置文件,或者尋找更適合處理大文件的工具。
最佳實(shí)踐
為了在使用Apache Commons Config時(shí)獲得最佳性能,咱們應(yīng)該:
- 適當(dāng)?shù)亟M織配置文件:避免創(chuàng)建過大或過于復(fù)雜的配置文件。
- 合理使用緩存:對于經(jīng)常訪問的配置,使用緩存可以提高性能。
- 優(yōu)化讀取頻率:如果可能,減少配置文件的讀取頻率,比如通過使用事件觸發(fā)的重新加載,而不是定時(shí)檢查。
第9章:總結(jié)
Apache Commons Config的優(yōu)勢
- 多格式支持:支持Properties、XML、JSON等多種常見的配置文件格式,滿足不同項(xiàng)目的需求。
- 靈活性:提供了多種配置讀取和寫入的方式,支持動態(tài)配置、層次化配置和組合配置等高級功能。
- 易于使用:簡單直觀的API,使得快速上手和使用變得容易。
- 集成友好:能夠輕松集成到各種Java項(xiàng)目中,與其他Apache Commons庫良好配合。
應(yīng)用場景
Apache Commons Config非常適合那些需要靈活配置管理的Java項(xiàng)目。無論是小型項(xiàng)目,還是需要復(fù)雜配置管理的大型應(yīng)用,它都是一個(gè)不錯的選擇。尤其是在多環(huán)境部署的場景下,它的優(yōu)勢更加明顯。
思考角度
在選擇和使用配置管理工具時(shí),咱們需要考慮以下幾個(gè)方面:
- 項(xiàng)目需求:評估項(xiàng)目對配置管理的具體需求,選擇最適合的工具。
- 未來擴(kuò)展:考慮項(xiàng)目未來的發(fā)展,選擇可以輕松擴(kuò)展和維護(hù)的配置管理方案。
- 性能要求:根據(jù)項(xiàng)目的性能要求,考慮配置管理工具的性能影響,并做出相應(yīng)的優(yōu)化。
- 安全性:對于涉及敏感信息的配置,考慮加密和安全訪問的需求。
通過本文,咱們學(xué)習(xí)了如何使用Apache Commons Config來管理Java項(xiàng)目中的配置。希望這些知識能幫助大家在實(shí)際工作中更高效地處理配置相關(guān)的問題。配置管理雖然是一個(gè)基礎(chǔ)性的話題,但它對于保證軟件質(zhì)量和靈活性來說是非常關(guān)鍵的。
以上就是Apache Commons Config管理配置文件核心功能使用的詳細(xì)內(nèi)容,更多關(guān)于Apache Commons Config配置的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springboot 中 druid+jpa+MYSQL數(shù)據(jù)庫配置過程
這篇文章主要介紹了springboot 中 druid+jpa+MYSQL數(shù)據(jù)庫配置,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08如何優(yōu)雅的拋出Spring Boot注解的異常詳解
這篇文章主要給大家介紹了關(guān)于如何優(yōu)雅的拋出Spring Boot注解的異常的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12SpringBoot集成Nacos的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot集成Nacos的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Java @Transactional與synchronized使用的問題
這篇文章主要介紹了Java @Transactional與synchronized使用的問題,了解內(nèi)部原理是為了幫助我們做擴(kuò)展,同時(shí)也是驗(yàn)證了一個(gè)人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會的2023-01-01java 基礎(chǔ)之JavaBean屬性命名規(guī)范問題
這篇文章主要介紹了java 基礎(chǔ)之JavaBean屬性命名規(guī)范問題的相關(guān)資料,需要的朋友可以參考下2017-05-05Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之健身俱樂部管理系統(tǒng)的實(shí)現(xiàn)
這是一個(gè)使用了java+SSM+Mysql+Jsp開發(fā)的健身俱樂部管理系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有俱樂部管理該有的所有功能,感興趣的朋友快來看看吧2022-02-02Java實(shí)現(xiàn)OTP(動態(tài)口令)服務(wù)
OTP是一種動態(tài)生成的短時(shí)有效密碼,用于身份驗(yàn)證,通常在登錄或執(zhí)行敏感操作時(shí)提供額外的安全保障,本文主要介紹了Java實(shí)現(xiàn)OTP(動態(tài)口令)服務(wù),感興趣的可以了解一下2025-03-03