Spring系列教程五: 依賴注入的方式詳解
依賴注入的概念
Spring中的依賴注入,稱為dependency Injection,Ioc的作用降低程式之間的耦合,依賴關係管理交給Spring來維護,在當前類中需要用到其他類的物件,由spring為我們提供,我們只需要在配置檔案中說明,依賴關係的維護,我們稱之為依賴注入
依賴注入的三種資料
基本資料型別和String、其他bean型別(在配置檔案中或者註解配置過的bean)、複雜型別/集合型別
依賴注入的三種方式
①使用建構函式 ②使用set方法提供 ③使用複雜型別注入/集合型別注入
建構函式注入
①目錄結構,介面實現類中屬性和方法
public class AccountServiceImpl implements IAccountService { //如果是經常變化的資料,並不適用於註冊的方式 private String name; private Integer age; private Date brithday; AccountServiceImpl(String name,Integer age,Date brithday){ this.name=name; this.age=age; this.brithday=brithday; } public void saveAccount(){ System.out.println("service中的saveAccount方法執行了...."+name+age+brithday); } }
②修改配置檔案
在配置檔案中,用使用標籤constructor-arg, 標籤出現的位置bean標籤內部
標籤中屬性 type:用於指定要注入的資料的資料型別,該資料也是建構函式中某個或者某些引數的型別,不能獨立實現注入,index:用於指定注入的資料給建構函式中指定索引位置的引數賦值,索引的位置從0開始,需要記索引,name:用於給指定後遭函式中指定名稱的引數賦值(常用的)
=======================以上三個用於給建構函式中引數賦值=========================
value:用於給基本型別和Strig提供資料,ref:就是引用指定其他的bean資料,它指的就是在Spring Ioc核心容器出現過的bean物件如下
<bean id="accountService" class="com.ithema.jdbc.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="name"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="brithday" ref="now"></constructor-arg>
</bean>
<!--配置一個日期物件-->
<bean id="now" class="java.util.Date"></bean>
③測試實現類,執行程式碼得到以下結果,成功實現了依賴注入
package com.ithema.jdbc.ui;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
public class Client {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
IAccountService as= (IAccountService) ac.getBean("accountService");
System.out.println(as);
as.saveAccount();
}
優勢:在獲取bean物件時候注入資料是必須的操作,否則物件無法建立成功 弊端:改變了bean物件的例項化方式,使我們在建立物件時候用不到這些資料也必須提供
set方式注入(是我們經常用的注入方式)
①在介面類中實現屬性的set的方法
package com.ithema.jdbc.service.impl;
import com.ithema.jdbc.service.IAccountService;
import java.util.Date;
/**
* 賬戶的業務層實現類
*/
public class AccountServiceImpl2 implements IAccountService {
//如果是經常變化的資料,並不適用於註冊的方式
private String name;
private Integer age;
private Date brithday;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBrithday(Date brithday) {
this.brithday = brithday;
}
public void saveAccount(){
System.out.println("service中的saveAccount方法執行了...."+"名字:"+name+"年紀:"+age+"生日:"+brithday);
}
}
②配置檔案中修改程式碼
<bean id="accountService2" class="com.ithema.jdbc.service.impl.AccountServiceImpl2">
<property name="name" value="Test"></property>
<property name="age" value="21"></property>
<property name="brithday" ref="now"></property>
</bean>
③測試類的執行,得到以下結果
package com.ithema.jdbc.ui;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
public class Client {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
IAccountService as= (IAccountService) ac.getBean("accountService2");
System.out.println(as);
as.saveAccount();
}
使用set方法實現注入
優勢:建立物件沒有明確的限制,可以直接使用預設的建構函式 劣勢:如果某個成員必須有值,則獲取物件時候,set無法執行
複雜型別方式的注入
①介面實現類set方法
package com.ithema.jdbc.service.impl;
import com.ithema.jdbc.service.IAccountService;
import java.lang.reflect.Array;
import java.util.*;
/**
* 賬戶的業務層實現類
*/
public class AccountServiceImpl3 implements IAccountService {
//複雜型別注入/集合注入
private String[] myStrs;
private List<String> myList;
private Map<String,String>myMap;
private Properties myPro;
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMyPro(Properties myPro) {
this.myPro = myPro;
}
public void saveAccount(){
System.out.println(Arrays.toString(myStrs));
System.out.println(myList);
System.out.println(myMap);
System.out.println(myPro);
}
}
②改變配置檔案中的程式碼
<bean id="accountService3" class="com.ithema.jdbc.service.impl.AccountServiceImpl3">
<property name="myStrs">
<array>
<value>AAAA</value>
<value>BBBB</value>
<value>CCC</value>
</array>
</property>
<property name="myList">
<list>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</list>
</property>
<property name="myMap">
<map>
<entry key="test1" value="AA"></entry>
<entry key="test2" value="BB"></entry>
<entry key="test3" value="CC"></entry>
</map>
</property>
<property name="myPro">
<props>
<prop key="test2">A</prop>
<prop key="test1">B</prop>
<prop key="test">C</prop>
</props>
</property>
</bean>
③測試類的執行,執行的結果如下
package com.ithema.jdbc.ui;
import org.springframework.core.io.ClassPathResource;
import javax.annotation.Resource;
public class Client {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
IAccountService as= (IAccountService) ac.getBean("accountService3");
System.out.println(as);
as.saveAccount();
}