Spring IoC
public ? class ?Foo? {①
??
private ?String?name;
??
private ? int ?age;
??
public ?String?toString() {
?????
return ? " The?Foo's?Name?is?:? " ? + ? this .name? + ? " ?The?Foo's?Age?is?:? " ? + ? this .age;
??}

??
public ?String?getName()? { }
??
public ? void ?setName(String?name)? { }
??
public ? int ?getAge()? { }
??
public ? void ?setAge( int ?age)? { }
}


public ? class ?Bar? {②
??
private ?String?address;
??
public ?String?toString() {
?????
return ? " The?Bar's?Address?is?:? " ? + ? this .address;
??}

??
public ?String?getAddress()? { }
??
public ? void ?setAddress(String?address)? { }
}


public ? class ?Base? {③
??
private ?Foo?foo;
??
private ?Bar?bar;
??
public ?String?toString() {
?????
return ? " Base?:?[ " ? + ? this .foo.toString()? + " ? " + ? this .bar.toString() + ? " ] " ;
??}

??
public ?Foo?getFoo()? { }
??
public ? void ?setFoo(Foo?foo)? { }
??
public ?Bar?getBar()? { }
??
public ? void ?setBar(Bar?bar)? { }
}



<? xml?version="1.0"?encoding="UTF-8" ?>
< beans? xmlns =" " >
??
< bean? id ="foo" ?class ="com.tony.test.Foo" >
?????
< property? name ="name" ?value ="Tony" />
?????
< property? name ="age" ?value ="27" />
??
</ bean? >
??
< bean? id ="bar" ?class ="com.tony.test.Bar" >
?????
< property? name ="address" ?value ="China?Tianjin" />
??
</ bean >
??
< bean? id ="base" ?class ="com.tony.test.Base" >
?????
< property? name ="foo" >
????????
< ref? local ="foo" />
?????
</ property >
?????
< property? name ="bar" >
????????
< ref? local ="bar" />
?????
</ property >
??
</ bean >
</ beans >

import ?org.springframework.context.ApplicationContext;
import ?org.springframework.context.support.ClassPathXmlApplicationContext;
public ? class ?MainClass? {④
??
public ? static ? void ?main(String[]?args)? {????
????????String[]?locations?
= ? { " spring-config-beans.xml " } ;????
????????ApplicationContext?ctx?
= ? new ?ClassPathXmlApplicationContext(locations);????
????????Base?main?
= ?(Base)?ctx.getBean( " base " );⑤???
????????System.out.println(main);⑥???
???}

}


我們來看看上面代碼的含義,首先在代碼①和②處我們分別定義了兩個名為Foo和Bar的Bean,在③處我們通過set方法將兩個Bean注入進Base類中,并且在Base類中定義了toString方法來打印出Foo和Bar的信息,在④處我們定義了一個MainClass來執(zhí)行我們的代碼,在⑤處我們通過getBean獲得配置文件中配置的id為base的Bean并在⑥出將其信息打印至控制臺,控制臺輸出信息如下:
Base : [The Foo's Name is : Tony The Foo's Age is : 27 The Bar's Address is : China Tianjin]
看到上面習以為常的配置信息和set get方法我們根本不會有任何想法,可是當我們看到了Spring2.5注釋特性的時候我們發(fā)現自己真的錯了,程序竟然還可以寫成這么簡單。

三、使用 @Autowired 注釋
import ?org.springframework.beans.factory.annotation.Autowired;
public ? class ?Base? {
??@Autowired① 使用了一個名為Autowired的注釋
??
private ?Foo?foo;
??@Autowired②
??
private ?Bar?bar;
??
public ?String?toString() {
?????
return ? " Base?:?[ " ? + ? this .foo.toString()? + " ? " + ? this .bar.toString() + ? " ] " ;
??}

}



<!-- ?該?BeanPostProcessor?將自動對標注?@Autowired?的?Bean?進行注入? --> ③??
??
< bean? class ="org.springframework.beans.factory.annotation.
??????????????????????????????AutowiredAnnotationBeanPostProcessor"
/>
??
??
< bean? id ="foo" ?class ="com.tony.test.Foo" >
?????
< property? name ="name" ?value ="Tony" />
?????
< property? name ="age" ?value ="27" />
??
</ bean >
??
< bean? id ="bar" ?class ="com.tony.test.Bar" >
?????
< property? name ="address" ?value ="China?Tianjin" />
??
</ bean >
??
<!-- ?此時移除了Base的配置信息? --> ?④
??
< bean? id ="base" ?class ="com.tony.test.Base" />

我們在①和②處使用了@Autowired注釋,它可以對類的成員變量、方法及構造函數進行標注,完成自動裝配的工作,在③處我們?yōu)榱耸笯Autowired注釋生效必須在Spring容器中聲明AutowiredAnnotationBeanPostProcessor Bean它通過掃描 Spring 容器中所有 Bean,當發(fā)現 Bean 中擁有 @Autowired 注釋時就找到和其相匹配(默認按類型匹配)的 Bean,并將其注入,而此時我們在聲明Base的時候(④處)就不用寫它的配置信息了,更可以將Base類中的set和get方法刪除。@Autowired還可以通過類的構造函數來進行自動裝配。

在默認情況下使用 @Autowired 注釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將拋出 BeanCreationException 異常,并指出必須至少擁有一個匹配的 Bean


import ?org.springframework.beans.factory.annotation.Autowired;
public ? class ?Base? {
??
private ?Foo?foo;
??
private ?Bar?bar;
??@Autowired
??
public ?Base(Foo?foo,Bar?bar) {?①
?????
this .foo? = ?foo;
?????
this .bar? = ?bar;
??}

??
public ?String?toString() {
?????
return ? " Base?:?[ " ? + ? this .foo.toString()? + " ? " + ? this .bar.toString() + ? " ] " ;
??}

}


我們增加了一個構造函數,通過它來對我們的成員變量進行賦值,我們同時也為這個構造函數添加了@Autowired注釋(①處)使其可以自動將Foo和Bar兩個成員變量裝配進來。


當不能確定 Spring 容器中一定擁有某個類的 Bean 時,可以在需要自動注入該類 Bean 的地方可以使用 @Autowired(required = false),這等于告訴 Spring:在找不到匹配 Bean 時也不報錯

四、使用 @Qualifier 注釋
有時我們會遇到這樣一種情況,我們定義了兩個類型相同數據不同的Bean,我們此時需要用到其中一個Bean來供我們使用,使用@Qualifier注釋就可以滿足我們的要求,當使用@Qualifier注釋時自動注入的策略就從 byType 轉變成 byName 了。
< bean? id ="bar" ?class ="com.tony.test.Bar" >
??
< property? name ="address" ?value ="China?Tianjin" />
</ bean >
< bean? id ="bar2" ?class ="com.tony.test.Bar" >
??
< property? name ="address" ?value ="China?Beijing" />
</ bean >

import ?org.springframework.beans.factory.annotation.Autowired;
import ?org.springframework.beans.factory.annotation.Qualifier;
public ? class ?Base? {
??
private ?Bar?bar;
??@Autowired ③
??
public ?Base(@Qualifier( " bar2 " )Bar?bar) { ④
?????
this .bar? = ?bar;
??}

??
public ?String?toString() {
?????
return ? " Base?:?[ " + ? this .bar.toString() + ? " ] " ;
??}

}


①和②處我們分別定義了兩個類型為Bar的Bean,②處Bar的address為China Beijing并且Bean的名稱為bar2,在代碼清單4.2的③處我們同樣使用了@Autowired注釋為Bar的構造函數進行自動裝配,可是在④處我們通過@Qualifier("bar2")來明確指定我們需要將id為bar2的Bean裝配進來。我們還可以為成員變量使用@Qualifier注釋。
import ?org.springframework.beans.factory.annotation.Autowired;
import ?org.springframework.beans.factory.annotation.Qualifier;
public ? class ?Base? {
??@Autowired?①
??@Qualifier(
" bar2 " )?②
??
private ?Bar?bar;
??
public ?String?toString() {
?????
return ? " Base?:?[ " + ? this .bar.toString() + ? " ] " ;
??}

}



五、使用 @Component 注釋

使用了@Autowired注釋后我們發(fā)現自動注入真的非常簡單,但是我們還是得在配置文件中定義相應的<Bean>,如果我們能在配置文件中完全移除Bean的定義那就更好了,Spring2.5就為我們提供了這一可能。
import ?org.springframework.stereotype.Component;
@Component?①
public ? class ?Bar? {
??
private ?String?address? = ? " China?Tianjin " ;
??
public ?String?toString() {
?????
return ? " The?Bar's?Address?is?:? " ? + ? this .address;
??}

}


import ?org.springframework.stereotype.Component;
@Component(
" base " )?②
public ? class ?Base? {
??@Resource
??
private ?Bar?bar;
??
public ?String?toString() {
?????
return ? " Base?:?[ " + ? <spa
分享到:
評論