利用Spring載入參數配置文件
我以為工程中的數據分為兩種:
- 項目內獲取:配置文件或者配置中心
- 項目外獲取:外界的參數等
我們項目的配置參數是寫在配置文件中的,那麼這些參數是怎樣載入到項目中去的呢?
- 添加Spring依賴
- 添加配置文件,包含spring配置文件和參數配置文件
- 測試驗證
先看下工程的架構(典型的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 |