425
技術社區[雲棲]
適應各種開發,測試,線上,線下環境的Spring配置方式
背景
假設開發了一個中間件,比如是一個緩存係統,這個中間件要配置一個IP地址,還要配置一個Factory,從這個Factory裏得到一個client,如:
<bean name="cacheFactory" > <property name="address" value="192.168.1.100"/> </bean> <bean name="cacheClient" factory-bean="cacheFactory" factory-method="getClient" />
然後這個中間件有三個集群(clusterA, clusterB, clusterC),分別給不同的業務使用,那就這時會有很多的配置的麻煩。
- 從使用者的角度出發,應用不喜歡引入一堆的配置,它們隻希望import一個配置文件,然後在代碼裏用@AutoWried注入一個Bean,就可以使用了。
- Spring Bean被覆蓋的風險。
如果兩個不同的業務都使用了這個cache,然後它們的jar包又再被第三個業務引用,那麼它們都import了一個cache service的配置,那麼就有可能出現後麵的Bean定義被前麵的覆蓋了。而Spring默認不處理這種Bean重複定義的問題。
- @AutoWried 注入的問題。和上一個問題類似,@AutoWried注入時如果沒有配置@Qualifier,那麼如果某個類有多個Bean實例,那麼就有可能出現Bean注入混亂的情況。
- 線上環境臨時切換。必須要支持線上臨時修改配置。
- 開發者無需配置。要提供默認值的配置,開發者不用做配置就可以直接在本地和測試環境運行代碼。
- 靜默發布新版配置。比如當集群遷移了,IP地址變換了,應用不用修改代碼和配置,隻需要用Maven重新打包即可。
可以利用的技術
spring profile,,@AutoWried,@Qualifier, PropertyPlaceholderConfigurer,PropertyOverrideConfigurer。
profile,PropertyPlaceholderConfigurer等的相關,不一一介紹了。如果有不明白的,可以到spring的文檔裏參考下。
簡要列舉下是如何解決上麵的問題的。
1.在緩存中間件的jar包裏放上三個集群的默認配置:
2.看下spring-cacheClusterA.xm裏的內容:
<beans pro> <bean > <property name="address" value="${cache.address.clusterA:127.0.0.1}"/> </bean> <bean name="cacheClusterAClient" factory-bean="cacheClusterAFactory" factory-method="getClient" /> </beans> <beans pro> <bean > <property name="address" value="${cache.address.clusterA:192.168.1.101}"/> </bean> <bean name="cacheClusterAClient" factory-bean="cacheClusterAFactory" factory-method="getClient" /> </beans> <beans pro> <bean > <property name="address" value="${cache.address.clusterA:10.10.1.10}"/> </bean> <bean name="cacheClusterAClient" factory-bean="cacheClusterAFactory" factory-method="getClient" /> </beans>
裏麵定義了三個profile:dev,test,product。這三個profile分別對應開發,測試,線上三種環境。
而在具體bean的配置上,用了一些"${}"這樣的占位符,另外還為它們配置了默認值。
PropertyPlaceholderConfigurer,PropertyOverrideConfigurer可以配置默認值,估計這功能比較少人知道 。
這樣就解決了不同環境,還要有默認配置的問題。
3.使用者的使用方法
假定使用者要用到clusterA和clusterB這兩個集群,那麼可以這樣配置:
<context:property-placeholder location="classpath:env.properties" /> <import resource="cacheConfigDefault/spring-cacheClusterA.xml" /> <import resource="cacheConfigDefault/spring-cacheClusterB.xml" />
import了緩存中間件的默認配置,然後還用placeholder加載了一個env.properties的環境變量文件。
那麼對於spring-cacheClusterA.xml和spring-cacheClusterB.xml裏的address這個屬性,如果沒有在env.properties裏有配置,則會使用默認配置。
如果想要修改,如修改cacheClusterA的配置,則可以在env.properties裏加下:
#if comment this, will use the default value cache.address.clusterA=testClusterAAddress
那麼clusterA使用的就是用戶的配置,而不是所依賴的jar包的默認配置了。
詳細代碼
再多詳細的代碼和配置,可以到這裏找到演示的代碼:
https://github.com/hengyunabc/spring-config
其它的一些東東
調試spring placeholder時,或者線上查看placeholder到底有沒有工作時,可以把spring的log級別調為TRACE,這樣就可以看到很多有用的信息了。
最後更新:2017-04-03 12:54:50