Spring IOC 反轉控制

來源:互聯網
上載者:User

Spring IOC

     IOC(Inversion of Control),譯作反轉控制,其功能是將類之間的依賴轉移到外部的設定檔中, 避免在調用類中寫入程式碼實作類別,因此也被稱作依賴注入(Dependency Injection)。在以往的開發中, 通常利用原廠模式(Factory)來解決此類問題,其實不管是原廠模式還是依賴注入,調用類與實作類別不可 能沒有任何依賴,原廠模式中工廠類通常根據參數來判斷該執行個體化哪個實作類別,Spring IOC將需要執行個體的 類在設定檔檔案中配置。使用Spring IOC能得到原廠模式同樣的效果,而且編碼更加簡潔。看段代碼比較 一下:

一、用原廠模式來實現

例 1.1. Product.java

public interface Product 

{

public void execute();

}


例 1.2. ConcreteProductA.java

public class ConcreteProductA implements  Product

{

public void execute()

{

...

}

}


例 1.3. ConcreteProductB.java

public class ConcreteProductB implements  Product

{

public void execute()

{

...

}

}


例1.4. Factory.java

public class Factory

{



public Product CreateProduct(object param)

{

return ConstructObjects(param);

}



private Product ConstructObjects(object param)

{

...

}

}


例 1.5. Client.java(調用類)

public class Client

{

public Client()

{

//執行個體化ConcreteProductA

Product product = Factory.CreateProduct(paramA);



//執行個體化ConcreteProductB

Product product = Factory.CreateProduct(paramB);

...

}

}


在ConstructObjects方法中設定執行個體化實作類別的邏輯,這樣對於調用類來說,不直接執行個體化實作類別,縱然實作類別發生變化, 調用代碼仍然可以不作修改,給維護與擴充帶來便利。

二、Spring IOC實現

例 1.6. SpringConfig.xml

<bean id="productA" class="ConcreteProductA" />

<bean id="productB" class="ConcreteProductB" />




例 1.7. Client.java(調用類)

public class Client

{

public Client()

{

//執行個體化ConcreteProductA

Product product = (Product)InitSpring.getObject("productA");



//執行個體化ConcreteProductB

Product product = (Product)InitSpring.getObject("productB");

...

}

}


調用代碼中沒有寫入程式碼實作類別,比較原廠模式,少了Factory類。

Spring為依賴注入提供三種實現方式:介面注入、設值注入、構造注入。利用這些可以靈活的解決 類之間的依賴關係,讓你為所欲為的組裝代碼。與其說Spring IOC是一個工具,還不如說搭建了一 個思想的舞台。繼續看代碼:

來實現一個操作多個資料來源的切換

例 1.8. DataSource.java

public class DataSource

{

private String driverClassName;

private String url;

private String username;

private String password;



public String getDriverClassName()

{

return this.driverClassName;

}



public void setDriverClassName(String driverClassName)

{

this.driverClassName = driverClassName;

}



public String getUrl()

{

return this.url;

}



public void setUrl(String url)

{

this.url = url;

}



public String getUsername()

{

return this.Username;

}



public void setUsername(String username)

{

this.username = username;

}



public String getPassword()

{

return this.password;

}



public void setPassword(String password)

{

this.password = password;

}

}


例 1.9. DataAccessor.java

public class DataAccessor

{

private DataSource dataSource;

public void setDriver(DataSource dataSource)

{

this.dataSource = dataSource;

}



public void save(String sql)

{

Statement s = getStatement();

try

{

s.getConnection().setAutoCommit(false);

int rows = s.executeUpdate(sql);

s.getConnection().commit();



}

catch(Exception e)

{

s.getConnection().rollback();

...

}

finally

{

...

}

}



private Statement getStatement()

{

Statement s;

try

{

Class.forName(dataSource.getDriverClassName()).newInstance();

java.sql.Connection conn =

java.sql.DriverManager.getConnection(dataSource.getUrl(),dataSource.getUser(),dataSource.getPassword());

try

{

s = c.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

}

}

catch(Exception e)

{

...

}

return s;

}

}


例 1.10. BussinessA.java

public class BussinessA

{

private DataAccessor dao;

public void setDao(DataAccessor dao)

{

this.dao = dao;

}



public void execute()

{

dao.save("insert into tb1 ...");

}

}


例 1.11 BussinessB.java

public class BussinessB

{

private DataAccessor dao;

public void setDao(DataAccessor dao)

{

this.dao = dao;

}



public void execute()

{

dao.save("insert into tb2 ...");

}



}


全部代碼就這樣了,執行BussinessA.java、BussinessB.java代碼即可完成資料插入操作,從代碼中看, 這兩個類具體操作的是什麼資料庫?什麼樣的操作細節?讓你失望了,代碼中找不到這樣的關聯,看設定檔吧:

例 1.12. SpringConfig.xml

<bean id="dataSourceA" class="DataSource" destroy-method="close">

<property name="driverClassName"><value>org.gjt.mm.mysql.Driver</value></property>

<property name="url">

<value>jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=GBK</value>

</property>

<property name="username"><value>root</value></property>

<property name="password"><value></value></property>

</bean>



<bean id="dataSourceB" class="DataSource" destroy-method="close">

<property name="driverClassName"><value>org.gjt.mm.mysql.Driver</value></property>

<property name="url">

<value>jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=GBK</value>

</property>

<property name="username"><value>root</value></property>

<property name="password"><value></value></property>

</bean>



<bean id="daoA" class="DataAccessor">

<property name="dataSource">

<ref local="dataSourceA"/>

</property>

</bean>



<bean id="daoB" class="DataAccessor">

<property name="dataSource">

<ref local="dataSourceB"/>

</property>

</bean>



<bean id="bussinessA" class="BussinessA">

<property name="dao">

<ref local="daoA"/>

</property>

</bean>



<bean id="bussinessB" class="BussinessB">

<property name="dao">

<ref local="daoB"/>

</property>

</bean>




看完設定檔應該明白了,這裡承擔了所有的依賴關係。

  • 首先,我們通過設值注入方法設定資料來源相關參數

  • 然後,我們將資料來源執行個體注入給資料訪問類

  • 最後,我們為每個具體業務類注入相應訪問器

是不是感覺想玩積木似的,在組裝你的代碼?

例 1.13. DaoTest.java

public void testSave()

{

BussinessA bussinessA = (BussinessA)InitSpring.getObject("bussinessA");

bussinessA.execute();



bussinessB bussinessB = (BussinessB)InitSpring.getObject("bussinessB");

bussinessB.execute();

}


執行這段測試代碼,資料庫Test1、Test2中tb1、tb2表將分別插入對應的資料,從實現代碼來看操作多個資料庫和 操作一個資料庫完全一樣,即使當資料來源,資料訪問類不斷變化,應用代碼也可以做到不用任何修改。

希望看完本章節的內容能讓讀者與我共鳴,Spring IOC是一種優雅的思想,藉助它發揮你無窮的想象吧。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.