依賴注入方式:Spring支持兩種依賴注入方式,分別是屬性注入和構造函數注入。還有工廠方法注入方式。
依賴注入還分為:注入依賴對象可以采用
手工裝配或
自動裝配,在實際應用開發中建議使用手工裝配,因為自動裝配會產生許多未知情況,開發人員無法預見最終的裝配結果。
手工裝配依賴對象又分為3種方式:
1、編程方式(寫的過程中向BeanFactory去注冊)
2、是在XML文件中,通過在bean節點下配置;如上面講到的使用屬性的setter方法注入依賴對象和使用構造器方法注入依賴對象都是這種方式。
3、就是在java代碼中使用注解的方式進行裝配,在代碼中加入
@Resource或者
@Autowired等,怎樣使用注解的方式來為某個bena注入依賴對象呢?
自動裝配依賴對象分為2種方式:
1、配置文件的bean中增加autowire
2、也可以選擇在beans中加入default-autowire屬性,為所有bean設置默認自動裝配
Spring中提供了自動裝配依賴對象的機制,但是在實際應用中並不推薦使用自動裝配,因為自動裝配會產生未知情況,開發人員無法預見最終的裝配結果。
自動裝配是在配置文件中實現的,如下:
<bean id="***" class="***" autowire="byType">
只需要配置一個autowire屬性即可完成自動裝配,不用再配置文件中寫<property>,但是在類中還是要生成依賴對象的setter方法。
Autowire的屬性值有如下幾個:
· byType 按類型裝配 可以根據屬性類型,在容器中尋找該類型匹配的bean,如有多個,則會拋出異常,如果沒有找到,則屬性值為null;
· byName 按名稱裝配 可以根據屬性的名稱在容器中查詢與該屬性名稱相同的bean,如果沒有找到,則屬性值為null;
· constructor 與byType方式相似,不同之處在與它應用於構造器參數,如果在容器中沒有找到與構造器參數類型一致的bean,那么將拋出異常;
· autodetect 通過bean類的自省機制(introspection)來決定是使用constructor還是byType的方式進行自動裝配。如果發現默認的構造器,那么將使用byType的方式。
---------------分割線-----------------------------------------------------------------------------------------------------
示例:
一、使用屬性setter方法注入
下面是Bean和beans-config.xml文件。
public class HelloBean { private String helloWord; //...省略getter、setter方法 }
xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="helloBean" class="onlyfun.caterpillar.HelloBean"> <property name="helloWord"> <value>Hello!Justin!</value> </property> </bean> </beans>
java:
public class SpringDemo { public static void main(String[] args) { Resource rs = new FileSystemResource("beans-config.xml"); BeanFactory factory = new XmlBeanFactory(rs); HelloBean hello = (HelloBean) factory.getBean("helloBean"); System.out.println(hello.getHelloWord()); } }
二、使用constructor方式完成注入
其中xml配置有如下方式:
在配置文件中配置該類的bean,並配置構造器,在配置構造器中用到了<constructor-arg>節點,該節點有四個屬性:
· index是索引,指定注入的屬性,從0開始,如:0代表personDao,1代表str屬性;
· type是指該屬性所對應的類型,如Persondao對應的是com.aptech.dao.PersonDAO;
· ref 是指引用的依賴對象;
· value 當注入的不是依賴對象,而是基本數據類型時,就用value;
java代碼:
public class HelloBean { private String name; private String helloWord; // 建議有要無參數建構方法 public HelloBean() { } public HelloBean(String name, String helloWord) { this.name = name; this.helloWord = helloWord; } //...省略getter、setter方法 }
xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="helloBean" class="onlyfun.caterpillar.HelloBean"> <constructor-arg index="0"> <value>Justin</value> </constructor-arg> <constructor-arg index="1"> <value>Hello</value> </constructor-arg> </bean> </beans>
java代碼:
public class SpringDemo { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext("beans-config.xml"); HelloBean hello = (HelloBean) context.getBean("helloBean"); System.out.print("Name: "); System.out.println(hello.getName()); System.out.print("Word: "); System.out.println(hello.getHelloWord()); } }
三、屬性參考
public
class HelloBean {
private String helloWord;
private Date date;
//...省略getter、setter方法
}
private String helloWord;
private Date date;
//...省略getter、setter方法
}
<
beans
>
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
< property name ="date" >
< ref bean ="dateBean" />
</ property >
</ bean >
</ beans >
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
< property name ="date" >
< ref bean ="dateBean" />
</ property >
</ bean >
</ beans >
public
class SpringDemo {
public static void main(String[] args) {
ApplicationContext context =
new FileSystemXmlApplicationContext( "beans-config.xml");
HelloBean hello = (HelloBean) context.getBean( "helloBean");
System.out.print(hello.getHelloWord());
System.out.print( " It's ");
System.out.print(hello.getDate());
System.out.println( ".");
}
}
public static void main(String[] args) {
ApplicationContext context =
new FileSystemXmlApplicationContext( "beans-config.xml");
HelloBean hello = (HelloBean) context.getBean( "helloBean");
System.out.print(hello.getHelloWord());
System.out.print( " It's ");
System.out.print(hello.getDate());
System.out.println( ".");
}
}
四、“byType”自動綁定
將“三”中的配置文件改為下面,即可完成bean屬性的按類型自動綁定。
<
beans
>
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="byType" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="byType" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
五、“byName”自動綁定
將“三”中的配置文件改為下面,即可完成bean屬性的按名稱自動綁定。
<
beans
>
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="byName" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="byName" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
六、“constructor”自動綁定
將“三”中的配置文件改為下面,即可完成bean屬性的按構造方法自動綁定。在建立依賴關系時,Srping容器會試圖比對容器中的Bean實例類型,及相關的構造方法上的參數類型,看看在類型上是否符合,如果有的話,則選用該構造方法來建立Bean實例。如果無法綁定,則拋出org.springframework.beans.factory.UnsatisfiedDependencyException異常。
<
beans
>
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="constructor" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="constructor" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
七、“autodetect”自動綁定
將“三”中的配置文件改為下面,即可完成bean屬性的自動綁定,這個自動綁定是Spring會嘗試用入constructor來處理依賴關系的建立,如果不行,則再嘗試用byType類建立依賴關系。
<
beans
>
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="autodetect" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="autodetect" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
八、依賴檢查方式
在自動綁定中,由於沒辦法從定義文件中,清楚地看到是否每個屬性都完成設定,為了確定某些依賴關系確實建立,您可以假如依賴檢查,在<bean>標簽使用時設定"dependency-check",可以有四種依賴檢查方式:simple、objects、all、none。
simple:只檢查簡單的類型(像原生數據類型或字符串對象)屬性是否完成依賴關系,。
objects:檢查對象類型的屬性是否完成依賴關系。
all:則檢查全部的屬性是否完成依賴關系。
none:設定是默認值,表示不檢查依賴性。
<
beans
>
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="autodetect" dependeny-check ="all" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
< bean id ="dateBean" class ="java.util.Date" />
< bean id ="helloBean" class ="onlyfun.caterpillar.HelloBean" autowire ="autodetect" dependeny-check ="all" >
< property name ="helloWord" >
< value >Hello! </ value >
</ property >
</ bean >
</ beans >
九、集合對象注入
對於像數組、List、Set、Map等集合對象,在注入前必須填充一些對象至集合中,然后再將集合對象注入至所需的Bean時,也可以交由Spring的IoC容器來自動維護或生成集合對象,並完成依賴注入。
public
class SomeBean {
private String[] someStrArray;
private Some[] someObjArray;
private List someList;
private Map someMap;
public String[] getSomeStrArray() {
return someStrArray;
}
public void setSomeStrArray(String[] someStrArray) {
this.someStrArray = someStrArray;
}
public Some[] getSomeObjArray() {
return someObjArray;
}
public void setSomeObjArray(Some[] someObjArray) {
this.someObjArray = someObjArray;
}
public List getSomeList() {
return someList;
}
public void setSomeList(List someList) {
this.someList = someList;
}
public Map getSomeMap() {
return someMap;
}
public void setSomeMap(Map someMap) {
this.someMap = someMap;
}
}
private String[] someStrArray;
private Some[] someObjArray;
private List someList;
private Map someMap;
public String[] getSomeStrArray() {
return someStrArray;
}
public void setSomeStrArray(String[] someStrArray) {
this.someStrArray = someStrArray;
}
public Some[] getSomeObjArray() {
return someObjArray;
}
public void setSomeObjArray(Some[] someObjArray) {
this.someObjArray = someObjArray;
}
public List getSomeList() {
return someList;
}
public void setSomeList(List someList) {
this.someList = someList;
}
public Map getSomeMap() {
return someMap;
}
public void setSomeMap(Map someMap) {
this.someMap = someMap;
}
}
public
class Some {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
<?
xml
version
="1.0"
encoding
="UTF-8"
?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
< beans >
< bean id ="some1" class ="onlyfun.caterpillar.Some" >
< property name ="name" >
< value >Justin </ value >
</ property >
</ bean >
< bean id ="some2" class ="onlyfun.caterpillar.Some" >
< property name ="name" >
< value >momor </ value >
</ property >
</ bean >
< bean id ="someBean" class ="onlyfun.caterpillar.SomeBean" >
< property name ="someStrArray" >
< list >
< value >Hello </ value >
< value >Welcome </ value >
</ list >
</ property >
< property name ="someObjArray" >
< list >
< ref bean ="some1" />
< ref bean ="some2" />
</ list >
</ property >
< property name ="someList" >
< list >
< value >ListTest </ value >
< ref bean ="some1" />
< ref bean ="some2" />
</ list >
</ property >
< property name ="someMap" >
< map >
< entry key ="MapTest" >
< value >Hello!Justin! </ value >
</ entry >
< entry key ="someKey1" >
< ref bean ="some1" />
</ entry >
</ map >
</ property >
</ bean >
</ beans >
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
< beans >
< bean id ="some1" class ="onlyfun.caterpillar.Some" >
< property name ="name" >
< value >Justin </ value >
</ property >
</ bean >
< bean id ="some2" class ="onlyfun.caterpillar.Some" >
< property name ="name" >
< value >momor </ value >
</ property >
</ bean >
< bean id ="someBean" class ="onlyfun.caterpillar.SomeBean" >
< property name ="someStrArray" >
< list >
< value >Hello </ value >
< value >Welcome </ value >
</ list >
</ property >
< property name ="someObjArray" >
< list >
< ref bean ="some1" />
< ref bean ="some2" />
</ list >
</ property >
< property name ="someList" >
< list >
< value >ListTest </ value >
< ref bean ="some1" />
< ref bean ="some2" />
</ list >
</ property >
< property name ="someMap" >
< map >
< entry key ="MapTest" >
< value >Hello!Justin! </ value >
</ entry >
< entry key ="someKey1" >
< ref bean ="some1" />
</ entry >
</ map >
</ property >
</ bean >
</ beans >
public
class SpringDemo {
public static void main(String[] args) {
ApplicationContext context =
new FileSystemXmlApplicationContext(
"beans-config.xml");
SomeBean someBean =
(SomeBean) context.getBean( "someBean");
// 取得數組型態依賴注入對象
String[] strs =
(String[]) someBean.getSomeStrArray();
Some[] somes =
(Some[]) someBean.getSomeObjArray();
for( int i = 0; i < strs.length; i++) {
System.out.println(strs[i] + ","
+ somes[i].getName());
}
// 取得List型態依賴注入對象
System.out.println();
List someList = (List) someBean.getSomeList();
for( int i = 0; i < someList.size(); i++) {
System.out.println(someList.get(i));
}
// 取得Map型態依賴注入對象
System.out.println();
Map someMap = (Map) someBean.getSomeMap();
System.out.println(someMap.get( "MapTest"));
System.out.println(someMap.get( "someKey1"));
}
}
public static void main(String[] args) {
ApplicationContext context =
new FileSystemXmlApplicationContext(
"beans-config.xml");
SomeBean someBean =
(SomeBean) context.getBean( "someBean");
// 取得數組型態依賴注入對象
String[] strs =
(String[]) someBean.getSomeStrArray();
Some[] somes =
(Some[]) someBean.getSomeObjArray();
for( int i = 0; i < strs.length; i++) {
System.out.println(strs[i] + ","
+ somes[i].getName());
}
// 取得List型態依賴注入對象
System.out.println();
List someList = (List) someBean.getSomeList();
for( int i = 0; i < someList.size(); i++) {
System.out.println(someList.get(i));
}
// 取得Map型態依賴注入對象
System.out.println();
Map someMap = (Map) someBean.getSomeMap();
System.out.println(someMap.get( "MapTest"));
System.out.println(someMap.get( "someKey1"));
}
}
十、靜態工廠的方法注入
靜態工廠顧名思義,就是通過調用靜態工廠的方法來獲取自己需要的對象,為了讓spring管理所有對象,我們不能直接通過"工程類.靜態方法()"來獲取對象,而是依然通過spring注入的形式獲取:
同樣看關鍵類,這里我需要注入一個FactoryDao對象,這里看起來跟第一種注入一模一樣,但是看隨后的xml會發現有很大差別:
Spring的IOC配置文件,注意看<bean name="staticFactoryDao">指向的class並不是FactoryDao的實現類,而是指向靜態工廠DaoFactory,並且配置 factory-method="getStaticFactoryDaoImpl"指定調用哪個工廠方法:
十一、實例工廠的方法注入
實例工廠的意思是獲取對象實例的方法不是靜態的,所以你需要首先new工廠類,再調用普通的實例方法:
那么下面這個類沒什么說的,跟前面也很相似,但是我們需要通過實例工廠類創建FactoryDao對象:
最后看spring配置文件: