1. 概述
根據設計,標註了 @Repository、@Service、@Controller 等註解的類由 Spring 管理,並且注入配置非常容易和自然。但將配置傳遞給未直接由 Spring 管理的類卻不那麼簡單。
在這種情況下,我們可以使用基於 ClassLoader 的配置加載方式,或者簡單地在另一個 Bean 中實例化我們的類並手動設置所需的參數——這是推薦的做法,因為配置條目不需要存儲在 *.properties 文件中。
在本文中,我們將涵蓋使用 Java 的 ClassLoader 加載 *.properties 文件以及將 Spring 加載的配置注入到未管理類中的主題。
<h2><strong>2. 使用類加載器加載配置</strong></h2>
<p>簡單來説,<em>*.properties</em>文件是存儲配置信息的資源文件。我們不使用像Spring中那樣支持自動應用程序配置加載的第三方實現,而是可以使用Java的<em>ClassLoader</em>來實現相同的功能。</p>
<p>我們將創建一個容器對象,用於存儲在<em>resourceFileName</em>中定義的<em>Properties</em>。為了將配置填充到容器中,我們將使用<em>ClassLoader</em>。</p>
<p>讓我們定義一個<em>PropertiesLoader</em>類,該類實現<em>loadProperties(String resourceFileName)</em>方法:</p>
public class PropertiesLoader {
public static Properties loadProperties(String resourceFileName) throws IOException {
Properties configuration = new Properties();
InputStream inputStream = PropertiesLoader.class
.getClassLoader()
.getResourceAsStream(resourceFileName);
configuration.load(inputStream);
inputStream.close();
return configuration;
}
}每個 Class 對象都包含指向創建它的 ClassLoader 的引用;這是一個主要負責加載類別的對象,但在本教程中,我們將使用它來加載資源文件,而不是普通的 Java 類。 ClassLoader 會在類路徑上查找 resourceFileName。
之後,我們通過 getResourceAsStream API 將資源文件加載為 InputStream。
在上面的示例中,我們定義了一個可以解析 resourceFileName 的配置容器,該容器使用 load(InputStream) API。
load 方法實現了使用支持 “:” 或 “=” 作為分隔符的 *.properties 文件的解析,此外,以 “#” 或 “!” 作為新行開頭的字符也用作註釋標記,並導致該行被忽略。
最後,讓我們從我們的配置文件中讀取定義的配置條目的確切值:
String property = configuration.getProperty(key);3. 使用 Spring 加載配置
另一種解決方案是利用 Spring 的特性來處理一些低級別的文件加載和處理。
我們定義一個 Initializer,用於持有初始化我們自定義類的所需配置。在 Bean 初始化期間,框架將加載所有帶有 @Value 註解的字段,這些字段來自 *.properties 配置文件:
@Component
public class Initializer {
private String someInitialValue;
private String anotherManagedValue;
public Initializer(
@Value("someInitialValue") String someInitialValue,
@Value("anotherValue") String anotherManagedValue) {
this.someInitialValue = someInitialValue;
this.anotherManagedValue = anotherManagedValue;
}
public ClassNotManagedBySpring initClass() {
return new ClassNotManagedBySpring(
this.someInitialValue, this.anotherManagedValue);
}
}初始化器現在可以負責實例化未受Spring管理的類。
現在,我們只需訪問我們的初始化器實例並運行其initClass()方法來處理我們自定義的未受Spring管理類的實例化:
ClassNotManagedBySpring classNotManagedBySpring = initializer.initClass();一旦我們獲取了 Initializer 的引用,我們就能實例化我們的自定義 ClassNotManagedBySpring。
4. 總結
本快速教程重點介紹了將屬性讀取到非 Spring Java 類中的方法。