Spring入門(基於Java的容器註解之@Scope和基於泛型的自動裝配)
@Scope
在使用@Bean的時候,預設@Bean定義出來的註解是單例的,那麼有什麼方式可以指定它的範圍呢,我們使用@Scope。Bean的作用域包括singleton、prototype、request、session、global session。
@Scope裡邊的內容和我們之前說到的Bean的範圍是一樣的,預設value是singleton,可以使用prototype、request、session、global session。
在@Scope裡邊還有另外一個屬性proxyMode,即採用哪一種的代理方式,一種是基於介面的註解,還有一種是TARGET_CLASS,是對於類的代理。
然後看個例子,還是在前一篇的基礎上,在StoreConfig中有這樣的程式碼
@Bean(name = "stringStore")
@Scope(value="prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Store stringStore() {
return new StringStore();
}
設定value為prototype,它的意思是每一次請求都會建立一個新的物件。
寫一個單元測試的方法
@Test
public void testScope() {
Store store = super.getBean ("stringStore");
System.out.println(store.hashCode());
store = super.getBean("stringStore");
System.out.println(store.hashCode());
}
這裡邊取兩次物件,輸出物件hashCode看是否相同。若兩次不同則為正確。
基於泛型的自動裝配
@Configuration
public class MyConfiguration{
@Bean
public StringStore stringStore(){
return new StringStore();
}
@Bean
public IntegerStore integerStore(){
return new IntegerStore();
}
}
仍然是@Configuration配置兩個類StringStore和IntegerStore。
@Autowired
private Store<String> s1;
@Autowired
private Store<Integer> s2;
在進行@Autowired自動裝配的時候,兩個Store s1和s2,第一個是String第二個是Integer。也就是說通過這種泛型的方式來指定s1和s2分別對應哪一個bean。s1泛型裡邊指定的是String,那麼s1對應的應該是上邊的StringStore,s2對應IntegerStore。
還有另一種方法
@Autowired
private List<Store<Integer>> s;
也就是說在一個集合裡邊的Store物件泛型指定的都是Integer型別的。
例子
將之前的一些類進行修改
接口裡指定T泛型:
public interface Store<T> {}
然後在實現類指定它的泛型:
public class StringStore implements Store<String> {
public void init() {
System.out.println("This is init.");
}
public void destroy() {
System.out.println("This is destroy.");
}
}
寫一個IntegerStore實現Store介面並指定它的泛型
public class IntegerStore implements Store<Integer> {}
在StoreConfig類中進行宣告
@Autowired
private Store<String> s1;
@Autowired
private Store<Integer> s2;
@Bean
public StringStore stringStore() {
return new StringStore();
}
@Bean
public IntegerStore integerStore() {
return new IntegerStore();
}
@Bean(name = "stringStoreTest")
// public StringStore stringStoreTest() {
public Store stringStoreTest() {
System.out.println("s1 : " + s1.getClass().getName());
System.out.println("s2 : " + s2.getClass().getName());
return new StringStore();
}
裡邊有一個方法輸出s1和s2的類名。這個方法要注意,由於是借用之前的寫過的方法,所以型別是StingStore,但是s1在裝配的時候發現有兩個StringStore型別。正常情況下會把第一個@Bean註解的StringStore賦值給s1,但是有兩個StringStore,會失敗。所以把下邊的方法型別修改一下。
單元測試類:
@Test
public void testG() {
StringStore store = super.getBean("stringStoreTest");
}
getBean的時候就會得到StoreConfig中的stringStoreTest方法,還會輸出s1和s2兩個類的類名。輸出s1對應的StringStore,s2對應IntegerStore。
Autowire擴充套件內容,關於自定義qualifier註解
CustomeAutowireConfigurer是BeanFactoryPostProcessor的子類,通過它可以註冊自己的qualifier註解型別(即使沒有使用Spring的@Qualifier註解)
<bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>example.CustomQualifier</value>
</set>
</property>
</bean>
class指定類,這個類中有個屬性customQualifierTypes,具體有哪些型別,我們可以把自己定義的型別放在裡邊,注意這裡是Set,也就是說我們可以放很多個。
該AutowireCandidateResolver決定自動裝配的候選者:
-每個bean定義的autowire-candidate值
-任何<bean/>
中的default-autowire-candidates
[email protected]註解及使用CustomAutowireConfigurer的自定義型別。
很少會使用到