從零開始學spring-理解IOC

spring有所瞭解的都應該知道,spring貫穿始終的兩個重要的思想,一個是IOC(控制反轉),一個是DI(依賴注入),對於新手而言,這兩個概念比較難理解,我用自己的想法來解釋下

首先我們要知道在程序開發中爲什麼要使用spring框架。

這裏先引入兩個概念:耦合性、侵入性。簡單的講:耦合性,在Java中表現爲類之間的關係,耦合性強說明類之間的依賴關係強;侵入性:框架對代碼的侵入,比如你項目用了struts1,要改框架時發現改的東西太多了,比如actionForm等,所以struts1對代碼的侵入性是很高的。
在傳統的java開發中具有高度的耦合性和侵入型。一個項目中,一般一個類都要依賴很多其他的類來完成自己的操作,我們往往採用new這個類的對象來調用他的方法,這樣就造成了兩個類的依賴關係太強,改一個地方,往往牽扯很多類牽扯大量的代碼。侵入性上一段的例子可以明白。
當然EJB也可以解決耦合性和侵入性的問題,但是ejb太依賴服務器,屬於重量級的框架。
可以說在這樣的背景下,spring應運而生,一個輕量級的框架,解決傳統企業開發的複雜性;使用普通的javaBean代替EJB技術。可以管理對象和對象之間的依賴關係,我們不需要自己建立對象,把這部分工作全部轉交給容器完成,具有低耦合,對代碼沒有侵略性,對服務器沒有依賴性特點的框架。
而這個容器,即IOC.

如何理解IOC思想?

一個很流行的例子,我換了種說法,這樣更好理解:好比找女朋友,普通的方式是我們依賴各種關係找到這個女朋友(相當於new了對象),有一天分手了,而以前的那些關係也沒有了,要想找到新的女朋友就要依賴新的關係(重新 new另外一個對象),可以想象這個過程很麻煩。於是有了一種新的方式找對象——婚介所,這裏就是我們所說的IOC方式,你把你要求的對象的特徵告訴婚介所,他會直接給你找到一對象,沒有中間複雜的過程,你只管相處的事情就好了,new的過程不用管,不需要任何依賴關係,即使哪天要換了,再把需要的對象提交給婚介所就行了,你就會得到你想要的新的對象了。
事實上,使用ioc方式創建對象的目的,是爲了以“被動”的方式形成對象之間的依賴關係。傳統的開發過程中,不管是new,還是普通工廠,都需要目標對象主動創建、主動查找其需要的依賴對象 , 目標對象會將他的精力分散在不必要的非業務邏輯方面。IOC通過DI(依賴注入)把建立好的對象注入到目標對象中。

Spring IOC具體如何實現?

上文中的婚介所就是ioc管理對象的容器,實際上是一個xml文件,將對象配置在xml裏面,通過spring的工廠類進行解析,以“反射”的方式創建對象。
spring IOC容器的關鍵點:
* 必須將被管理的對象定義到spring配置文件中
* 必須定義構造函數或setter方法,讓spring將對象注入過來
我們可以通過下面這裏例子理解spring ioc的實現。本例使用spring 3.2
1.配置applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <bean id="userDao4MySqlImpl" class="com.bjsxt.spring.dao.UserDao4MySqlImpl"/>
    <bean id="userDao4OracleImpl" class="com.bjsxt.spring.dao.UserDao4OracleImpl"/>
    <bean id="userManager" class="com.bjsxt.spring.manager.UserManagerImpl">
        <!-- 構造方法注入 
        <constructor-arg ref="userDao4OracleImpl"/>
         -->
         <!-- setter方法注入 -->
         <property name="userDao" ref="userDao4OracleImpl"/>
    </bean>
</beans>

2.注入的類:
package com.bjsxt.spring.dao;

public interface UserDao {

    public void save(String username, String password);
}

package com.bjsxt.spring.dao;

public class UserDao4MySqlImpl implements UserDao {

    public void save(String username, String password) {
        System.out.println("--------UserDao4MySqlImpl.save()-------");
    }
}

package com.bjsxt.spring.dao;

public class UserDao4OracleImpl implements UserDao {

    public void save(String username, String password) {
        System.out.println("--------UserDao4OracleImpl.save()-------");
    }
}

3.被注入的類:

package com.bjsxt.spring.manager;

public interface UserManager {
    public void save(String username, String password);
}

package com.bjsxt.spring.manager;

import com.bjsxt.spring.dao.UserDao;

public class UserManagerImpl implements UserManager {
    /**
     * 兩種方式:如果這個類中需要注入對象,先建立對象屬性,
     *      在寫構造方法或者settet方法。
     * 
     */
    private UserDao userDao;

/*  public UserManagerImpl(UserDao userDao) {
        this.userDao = userDao;
    } */

    public void save(String username, String password) {
        this.userDao.save(username, password);
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

4.測試類:

package com.bjsxt.spring.client;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.bjsxt.spring.manager.UserManager;

public class Client {

    public static void main(String[] args) {
/*  傳統的通過new對象建立類之間的關係
 * UserManager userManager = new UserManagerImpl(new UserDao4OracleImpl());
        UserManager userManager = new UserManagerImpl(new UserDao4MySqlImpl());
        userManager.save("張三", "123");*/
/**
 * IOC思想     通過工廠類解析xml文件,以“反射”的方式創建對象:
 */
        BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserManager userManager = (UserManager)factory.getBean("userManager");
        userManager.save("張三", "123");
/**
 * IOC思想   實際的執行過程,這也是爲什麼需要setter方法或構造方法的原因:        
 */
//      UserManagerImpl userManager = new UserManagerImpl();
//      userManager.setUserDao(new UserDao4MySqlImpl());
//      userManager.save("張三", "123");
    }
}
這樣就實現了spring ioc思想。
本文完全個人理解,如有不對的地方,懇請指正。
原文鏈接:http://blog.csdn.net/frightingforambition/article/details/47974775
發佈了23 篇原創文章 · 獲贊 17 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章