前面我已經學過了,將一個bean引用注入到另一個bean的屬性或構造器參數中,這邊指的是將一個對象與另一個對象進行關聯。
我們學過的方法是在創建的時候根據new對象的時候,注入參數,如下:
@Bean public CompactDisc randomCd() { int choice = (int) Math.floor(Math.random() * 4); switch (choice) { case 0: return new RandomCd("dangNianQing"); case 1: return new RandomCd("qianNvYouHun"); case 2: return new RandomCd("wo"); default: return new RandomCd("chenMoShiJing"); } }
也可以在xml中配置的時候,注入:
<bean id="randomCd" class="com.bean.xml.RandomCd"> <constructor-arg index="0" value="當年情"/> <constructor-arg index="1" value="張國榮"/> </bean>
這些方法屬於的值屬於 硬編碼值。
有時候硬編碼是可以的,但有的時候,我們可能會希望避免硬編碼值,而是想讓這些值在運行時再確定。為了實現這些功能,Spring提供了兩種在運行時求值的方式:
- 屬性占位符(Property placeholder)。
- Spring表達式語言(SpEL)。
先看第一種的方法,屬性占位符,主要是使用@PropertySource注解和Environment
@Configuration @PropertySource(value = "/com/bean/java/cd.properties") public class CDPlayerConfig { @Autowired Environment environment; @Bean public CompactDisc randomCd() { int choice = (int) Math.floor(Math.random() * 4); switch (choice) { case 0: return new RandomCd(environment.getProperty("cd.dnq")); case 1: return new RandomCd(environment.getProperty("cd.qnyh")); case 2: return new RandomCd(environment.getProperty("cd.w")); default: return new RandomCd(environment.getProperty("cd.cmsj")); } } }
cd.properties內容為:
cd.dnq= dnq
cd.qnyh = qnyh
cd.w = w
cd.cmsj = cmsj
cd.properties在運行的時候會被加載到Spring的Environment 通過從Environment檢索可以得到文件中的屬性值,取值的方式有以下四種種:
- String getProperty(String var1);
- String getProperty(String var1, String var2);
- <T> T getProperty(String var1, Class<T> var2);
- <T> T getProperty(String var1, Class<T> var2, T var3);
第一個就是上面所用的key-value 鍵值對對於的key
第二個是指當指定key,沒有特定的value的時候,后面的值即是為默認值
第三個跟第四種相似,只不過他特定了一個類型,方便你用嗎,無需取完之后再去轉換
當然了Environment除了這些屬性,還有:
- String[] getActiveProfiles():返回激活profile名稱的數組;
- String[] getDefaultProfiles():返回默認profile名稱的數組;
- boolean acceptsProfiles(String... profiles):如果environment支持給定profile的話,就返回true。
上面的是java配置解析的 ,我們也來看看如何用xml跟自動掃描的方式來解析占位符
public CompactDisc randomCd(@Value("${cd.dnq}") String str) { System.out.println(str); }
xml方式
<bean id="randomCd" class="com.bean.xml.RandomCd"> <constructor-arg index="0" value="${cd.dnq}"/> <constructor-arg index="1" value="張國榮"/> </bean>
當然使用這些方法是要有前提的,需要配置PropertySourcesPlaceholderConfigurer,因為它能夠基於Spring Environment及其屬性源來解析占位符。
@Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){ return new PropertySourcesPlaceholderConfigurer(); }
xml中需要添加:
<context:property-placeholder />
讓我們再來看下第二種方法:Spring表達式語言進行裝配。SpEL表達式要放到“#{ ... }”之中,這與屬性占位符有些類似,屬性占位符需要放到“${ ... }”之中
SpEL的表達式學問還是很深的,我這里就學習點皮毛:
比如表達式為一個常量
#{3}
為一個小小的函數(T為類型)
#{T(System).currentTimeMillis()}
也可以引起其他bean的屬性,這里的dangNianQing為一個bean,可以獲得他的title屬性和方法
#{dangNianQing.title}
#{dangNianQing.play()}
還可以通過systemProperties對象引用系統屬性:
#{SystemProperties['cd.dnq']}
就先介紹這一點,等學的更多的時候,在貼上來。。。
以上就是Bean自動注入的學習筆記,如有錯,歡迎指出,謝謝~
