標籤:

利用Spring載入參數配置文件

我以為工程中的數據分為兩種:

  1. 項目內獲取:配置文件或者配置中心
  2. 項目外獲取:外界的參數等

我們項目的配置參數是寫在配置文件中的,那麼這些參數是怎樣載入到項目中去的呢?

  1. 添加Spring依賴
  2. 添加配置文件,包含spring配置文件和參數配置文件
  3. 測試驗證

先看下工程的架構(典型的maven工程)

spring的依賴略去,重點看下Spring的配置文件。

spring的配置文件的根標籤是<beans>,這也不難理解,spring是bean的管理框架。

對比maven,發現maven和spring是兩個不同層次的東西,但都是最基礎的管理工具

<context:component-scan base-package="com.meituan.blueprint"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/></context:component-scan><bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="locations"> <list> <value>classpath:spring/config.properties</value> </list> </property></bean><context:property-placeholder properties-ref="properties" trim-values="true"/>

config.properties文件只有兩行:

app.name=com.meituan.blueprintwork.date=20180305

java的VO類也非常簡單:

@Setter@Getter@ToString@Componentpublic class ConfigVO { @Value("${app.name}") private String appName; @Value("${work.date}") private Integer workDate;}

單元測試A(寫在src/main中)

ApplicationContext context = new ClassPathXmlApplicationContext("spring/applicationContext.xml");ConfigVO configVO = (ConfigVO) context.getBean("configVO");System.out.println(configVO);

單元測試B(寫在src/test中)

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:spring/applicationContext.xml")public class ResearchTest { @Resource private ConfigVO configVO; @Autowired private Properties properties; @Test public void configTest() { System.out.println(configVO.toString()); System.out.println(properties.toString()); }}

兩個case的輸出相同:ConfigVO(appName=com.meituan.blueprint, workDate=20180305)

其中單測B多一行輸出:{app.name=com.meituan.blueprint, work.date=20180305}。

java.util.Properties本質是一個map,它的父類是Hashtable<Object,Object>。

而在配置文件中只是聲明了PropertiesFactoryBean,兩者並不是同一個類

那麼問題來了,這個properties是怎麼被注入的呢?在配置文件中沒有聲明啊。

在網上並沒有搜索到相關信息,那麼只能獨身深入源碼了。幸好PropertiesFactoryBean足夠簡單,先看下它的繼承樹。

秘密就在於其中之一的介面:FactoryBean

public interface FactoryBean<T> { T getObject() throws Exception; Class<?> getObjectType(); boolean isSingleton();}

通過這個介面,Spring就可以偷梁換柱了。

寫到最後想起來參加工作後的第一個項目,讀取配置參數被封裝成一個靜態方法,每獲得一個參數居然都要讀一次文件。對比之下,立刻能感到Spring的便捷和強大。

更多細節請參考:spring <context:property-placeholder>使用說明


推薦閱讀:

Spring Cloud雲服務架構代碼結構構建
IOC和DI有什麼區別?
【spring指南系列】使用Redis進行消息傳遞
關於spring,mybatis,mvc等等框架?
Spring boot 進階之路

TAG:Spring |