1. 程式人生 > >【SSH進階之路】Spring的IOC逐層深入——依賴注入的兩種實現型別(四)

【SSH進階之路】Spring的IOC逐層深入——依賴注入的兩種實現型別(四)

        上篇博文,我們介紹了為什麼使用IOC容器,和IOC的設計思想以及IOC容器的優缺點,並且給大家轉載了一篇介紹IOC原理的博文,我們這篇主要給大家依賴注入的兩種方式,以及他們的優缺點。

       我們這篇博文還是使用上篇部落格中新增使用者的實力,只是給大家在注入物件的方式上發生一點點變化,為了讓大家更加容易接受。下面我們開始:

構造器注入

       構造器注入,即通過建構函式完成依賴關係的設定。我們看一下spring的配置檔案:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	     xmlns:aop="http://www.springframework.org/schema/aop"
	     xmlns:tx="http://www.springframework.org/schema/tx"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

	<!-- 使用spring管理物件的建立,還有物件的依賴關係 -->
	<bean id="userDao4Mysql" class="com.tgb.spring.dao.UserDao4MysqlImpl"/>

	<bean id="userDao4Oracle" class="com.tgb.spring.dao.UserDao4OracleImpl"/>
	
	<bean id="userManager" class="com.tgb.spring.manager.UserManagerImpl">
		<!-- (1)userManager使用了userDao,Ioc是自動建立相應的UserDao實現,都是由容器管理-->
		<!-- (2)在UserManager中提供建構函式,讓spring將UserDao實現注入(DI)過來 -->
		<!-- (3)讓spring管理我們物件的建立和依賴關係,必須將依賴關係配置到spring的核心配置檔案中 -->

		<constructor-arg ref="userDao4Oracle"/>
	</bean>
	
</beans>
我們再看一下,構造器表示依賴關係的寫法:
import com.tgb.spring.dao.UserDao;

public class UserManagerImpl implements UserManager{

	private UserDao userDao;

	//使用構造方式賦值
	public UserManagerImpl(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void addUser(String userName, String password) {

		userDao.addUser(userName, password);
	}
}

設值注入(Setter)

        設值注入模式在實際開發中得到了最廣泛的應用,在LZ看來,基於設值模式的依賴注入機制更加直觀、也更加的自然。我們看一下spring的配置檔案:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	     xmlns:aop="http://www.springframework.org/schema/aop"
	     xmlns:tx="http://www.springframework.org/schema/tx"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

	<!-- 使用spring管理物件的建立,還有物件的依賴關係 -->
	<bean id="userDao4Mysql" class="com.tgb.spring.dao.UserDao4MysqlImpl"/>

	<bean id="userDao4Oracle" class="com.tgb.spring.dao.UserDao4OracleImpl"/>
	
	<bean id="userManager" class="com.tgb.spring.manager.UserManagerImpl">
		<!-- (1)userManager使用了userDao,Ioc是自動建立相應的UserDao實現,都是由容器管理-->
		<!-- (2)在UserManager中提供建構函式,讓spring將UserDao實現注入(DI)過來 -->
		<!-- (3)讓spring管理我們物件的建立和依賴關係,必須將依賴關係配置到spring的核心配置檔案中 -->

		<property name="userDao" ref="userDao4Oracle"></property>
	</bean>
	
</beans>
我們再看一下,設值表示依賴關係的寫法:
import com.tgb.spring.dao.UserDao;

public class UserManagerImpl implements UserManager{

	private UserDao userDao;

	//使用設值方式賦值
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	@Override
	public void addUser(String userName, String password) {

		userDao.addUser(userName, password);
	}
}

       從上面的程式碼,我們可以發現,不管是構造器方式還是設值方式,只有兩處寫法不太一樣,一是配置spring的配置檔案,二是在依賴關係的寫法不同,但都能根據名稱區別開,下面我們再對比它們各自的優勢。

對比

相同點:

       構造器和設值的依賴注入實現模式均具備無侵入性的特點。並且這兩種實現方式各有特點,也各有優勢(一句經典廢話大笑)。

不同點:

      構造方法與設值方法最重要的不同點只是建立物件的時機不同。

      構造方法是當例項化物件時執行的即“在構造期即建立一個完整、合法的物件”,例如我們的Dao物件就想在例項化UserManager的時候傳值,那麼我們必須要用構造方法。如果我們沒有這樣的需求的話,我們完全可以使用設值方法。

構造器方式的優勢:

1、在構造期即建立一個完整、合法的物件。

2、避免了繁瑣的Setter方式的編寫,所有的依賴關係都在建構函式中設定。

3、沒有Setter方法,依賴關係在構造時由容器一次性設定,因此元件在被建立之後即處於相對“不變”的穩定狀態。

設值方式的優勢:

1、對於習慣了傳統JavaBean開發的程式設計師而言,通過setter方法設定依賴關係顯得更加直觀,更加自然。

2、如果依賴關係(或繼承關係)較為複雜,那麼構造方法的建構函式也會相當龐大(我們需要在建構函式中設定所有依賴關係),此時設值方式往往更為簡潔。

總結

        構造器方式和設值方式,各有千秋,而spring對這種型別的注入方式都提供了良好的支援。不過對於基於Spring開發的應用而言,設值方式使用的更加廣泛。