項(xiàng)目目錄結(jié)構(gòu)

image.png
配置管理類
import java.io.InputStream;
import java.util.Properties;
/**
* 配置管理組件
*
* 1、配置管理組件可以復(fù)雜,也可以很簡單,對(duì)于簡單的配置管理組件來說,只要開發(fā)一個(gè)類,可以在第一次訪問它的
* 時(shí)候,就從對(duì)應(yīng)的properties文件中,讀取配置項(xiàng),并提供外界獲取某個(gè)配置key對(duì)應(yīng)的value的方法
* 2、如果是特別復(fù)雜的配置管理組件,那么可能需要使用一些軟件設(shè)計(jì)中的設(shè)計(jì)模式,比如單例模式、解釋器模式
* 可能需要管理多個(gè)不同的properties,甚至是xml類型的配置文件
* 3、我們這里的話,就是開發(fā)一個(gè)簡單的配置管理組件,就可以了
*
* @author Administrator
*
*/
public class ConfigurationManager {
// Properties對(duì)象使用private來修飾,就代表了其是類私有的
// 那么外界的代碼,就不能直接通過ConfigurationManager.prop這種方式獲取到Properties對(duì)象
// 之所以這么做,是為了避免外界的代碼不小心錯(cuò)誤的更新了Properties中某個(gè)key對(duì)應(yīng)的value
// 從而導(dǎo)致整個(gè)程序的狀態(tài)錯(cuò)誤,乃至崩潰
private static Properties prop = new Properties();
/**
* 靜態(tài)代碼塊
*
* Java中,每一個(gè)類第一次使用的時(shí)候,就會(huì)被Java虛擬機(jī)(JVM)中的類加載器,去從磁盤上的.class文件中
* 加載出來,然后為每個(gè)類都會(huì)構(gòu)建一個(gè)Class對(duì)象,就代表了這個(gè)類
*
* 每個(gè)類在第一次加載的時(shí)候,都會(huì)進(jìn)行自身的初始化,那么類初始化的時(shí)候,會(huì)執(zhí)行哪些操作的呢?
* 就由每個(gè)類內(nèi)部的static {}構(gòu)成的靜態(tài)代碼塊決定,我們自己可以在類中開發(fā)靜態(tài)代碼塊
* 類第一次使用的時(shí)候,就會(huì)加載,加載的時(shí)候,就會(huì)初始化類,初始化類的時(shí)候就會(huì)執(zhí)行類的靜態(tài)代碼塊
*
* 因此,對(duì)于我們的配置管理組件,就在靜態(tài)代碼塊中,編寫讀取配置文件的代碼
* 這樣的話,第一次外界代碼調(diào)用這個(gè)ConfigurationManager類的靜態(tài)方法的時(shí)候,就會(huì)加載配置文件中的數(shù)據(jù)
*
* 而且,放在靜態(tài)代碼塊中,還有一個(gè)好處,就是類的初始化在整個(gè)JVM生命周期內(nèi),有且僅有一次,也就是說
* 配置文件只會(huì)加載一次,然后以后就是重復(fù)使用,效率比較高;不用反復(fù)加載多次
*/
static {
try {
// 通過一個(gè)“類名.class”的方式,就可以獲取到這個(gè)類在JVM中對(duì)應(yīng)的Class對(duì)象
// 然后再通過這個(gè)Class對(duì)象的getClassLoader()方法,就可以獲取到當(dāng)初加載這個(gè)類的JVM
// 中的類加載器(ClassLoader),然后調(diào)用ClassLoader的getResourceAsStream()這個(gè)方法
// 就可以用類加載器,去加載類加載路徑中的指定的文件
// 最終可以獲取到一個(gè),針對(duì)指定文件的輸入流(InputStream)
InputStream in = ConfigurationManager.class
.getClassLoader().getResourceAsStream("my.properties");
// 調(diào)用Properties的load()方法,給它傳入一個(gè)文件的InputStream輸入流
// 即可將文件中的符合“key=value”格式的配置項(xiàng),都加載到Properties對(duì)象中
// 加載過后,此時(shí),Properties對(duì)象中就有了配置文件中所有的key-value對(duì)了
// 然后外界其實(shí)就可以通過Properties對(duì)象獲取指定key對(duì)應(yīng)的value
prop.load(in);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取指定key對(duì)應(yīng)的value
*
* 第一次外界代碼,調(diào)用ConfigurationManager類的getProperty靜態(tài)方法時(shí),JVM內(nèi)部會(huì)發(fā)現(xiàn)
* ConfigurationManager類還不在JVM的內(nèi)存中
*
* 此時(shí)JVM,就會(huì)使用自己的ClassLoader(類加載器),去對(duì)應(yīng)的類所在的磁盤文件(.class文件)中
* 去加載ConfigurationManager類,到JVM內(nèi)存中來,并根據(jù)類內(nèi)部的信息,去創(chuàng)建一個(gè)Class對(duì)象
* Class對(duì)象中,就包含了類的元信息,包括類有哪些field(Properties prop);有哪些方法(getProperty)
*
* 加載ConfigurationManager類的時(shí)候,還會(huì)初始化這個(gè)類,那么此時(shí)就執(zhí)行類的static靜態(tài)代碼塊
* 此時(shí)咱們自己編寫的靜態(tài)代碼塊中的代碼,就會(huì)加載my.properites文件的內(nèi)容,到Properties對(duì)象中來
*
* 下一次外界代碼,再調(diào)用ConfigurationManager的getProperty()方法時(shí),就不會(huì)再次加載類,不會(huì)再次初始化
* 類,和執(zhí)行靜態(tài)代碼塊了,所以也印證了,我們上面所說的,類只會(huì)加載一次,配置文件也僅僅會(huì)加載一次
*
* @param key
* @return value
*/
public static String getProperty(String key) {
return prop.getProperty(key);
}
}
測(cè)試類
/**
* 配置管理組件測(cè)試類
* @author Administrator
*
*/
public class ConfigurationManagerTest {
public static void main(String[] args) {
String testkey1 = ConfigurationManager.getProperty("testkey1");
String testkey2 = ConfigurationManager.getProperty("testkey2");
System.out.println(testkey1);
System.out.println(testkey2);
}
}
配置文件my.properties
testkey1=testvalue1
testkey2=testvalue2