1. 程式人生 > >Spring入門(基於Java的容器註解之@Scope和基於泛型的自動裝配)

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的自定義型別。

很少會使用到