1. 程式人生 > >spring——控制反轉簡單例子

spring——控制反轉簡單例子

像前面部落格中提到struts框架,Hibernate框架似的,spring同樣也是一個開源的框架。使用框架的的優勢在於分層結構,每層有相應的框架,減少開發工作量,減少元件之間的耦合。struts框架應用web層,Hibernate框架應用持久層,spring應用兩者之間。

   我覺得,框架是出於聰明的賴人之手。聰明是說他們開發封裝每層框架,把複雜的操作全部封裝在框架中。而賴人是說他所有複雜的操作實現全部交給計算機來實現,減少人們的開發工作量,把工作的注意力集中在業務邏輯上。

   那我們來介紹一下struts框架。

       spring框架是一個開源的輕量級的基於IOC與AOP核心技術的容器框架,主要是解決企業的複雜操作實現。

   那IOC與AOP,到底如何解釋呢,在看spring視訊中,兩個專業術語一定必須要懂得。

       IOC:inverse of Control:控制反轉。意思是程式中的之間的關係,不用程式碼控制,而完全是由容器來控制。在執行階段,容器會根據配置資訊直接把他們的關係注入到元件中。同樣,這也是依賴注入的含義。依賴注入和控制反轉其實是一個概念。只不過強調的不同而已,依賴注入強調關係的注入是由容器在執行時完成,而控制反轉強調關係是由容器控制。其實本質是一樣的。

   用程式碼演示一下控制反轉是如何實現的。

1。新建一個普通的java專案。

2。引入相應的jar包。Spring.jar,log4j-1.2.14.jar(提供日誌功能的),commons-logging.jar

3。提供log4j.properties配置檔案。(日誌jar包可以不用新增)

4。提供配置檔案ApplicationContext.xml檔案

5。開始寫程式碼。

  1. package ioc.iocsample;  
  2. /** 
  3.  * 學校類 
  4.  * @author lhy 
  5.  * 
  6.  */  
  7. public class School {  
  8.    private String name;  
  9.    public School(String name)  
  10.    {  
  11.        this.name=name;  
  12.    }  
  13.    public void printInfo()  
  14.    {  
  15.        System.out.println("該學校的名稱是:"+name);  
  16.    }  
  17. }  
  1. package ioc.iocsample;  
  2. /** 
  3.  * 學生類 
  4.  * @author lhy 
  5.  * 
  6.  */  
  7. public class Student {  
  8.   public int id;  
  9.   public String name;  
  10.   private School school;  
  11. public int getId() {  
  12.     return id;  
  13. }  
  14. public void setId(int id) {  
  15.     this.id = id;  
  16. }  
  17. public String getName() {  
  18.     return name;  
  19. }  
  20. public void setName(String name) {  
  21.     this.name = name;  
  22. }  
  23. public School getSchool() {  
  24.     return school;  
  25. }  
  26. public void setSchool(School school) {  
  27.     this.school = school;  
  28. }    
  29. }  

 
     配置檔案:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xmlns:aop="http://www.springframework.org/schema/aop"  
  5.          xmlns:tx="http://www.springframework.org/schema/tx"  
  6.          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  7.            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
  8.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">  
  9.  <bean id="school" class="ioc.iocsample.School">  
  10.        <constructor-arg index="0">  
  11.          <value>廊坊師院</value>  
  12.        </constructor-arg>  
  13.  </bean>  
  14.  <bean id="student" class="ioc.iocsample.Student">  
  15.      <property name="id"      value="001"/>  
  16.      <property name="name" value="張三"/>  
  17.      <property name="school"  ref ="school"/>  
  18.  </bean>  
  19. </beans>  


    客戶端進行測試,其中學生類Student中有School中的引用,測試該學生就讀的學校的名稱如下:

  1. package ioc.iocsample;  
  2. import org.springframework.beans.factory.BeanFactory;  
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  4. public class Client {  
  5.     public static void main(String[] args) {  
  6.         // TODO Auto-generated method stub  
  7.         BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");  
  8.         Student student=(Student)factory.getBean("student");  
  9.         student.getSchool().printInfo();  
  10.     }  
  11. }  


    其中,在程式中不用例項化學生類,學校類,直接由容器中的beanFactory直接建立,隱藏了建立了細節。同時,程式中也不用關心學生類與學校類之間的依賴關係,而由容器來進行負責,在執行的時候,容器會把屬性值及依賴關係注入學生類和學校類中的javabean中(其實在此School和Student就是一個javaBean。javaBean就是一個按照一定的原則封裝的java類而已。)

   其中依賴注入包括兩種:一種賦值注入(使用getter和setter方法);另一種使用構造器注入。

   看程式中student中的ID,name都是使用get,set來賦值的:那在配置檔案是如下配置:

       <property name="id"      value="001"/>
       <property name="name" value="張三"/>

   並且Student中的school屬性是School型別,則在容器中是如下配置的:

       <property name="school"  ref ="school"/>

   而在程式中的School中的name是構造器賦值的,則容器中是如下配置的:

      <constructor-arg index="0">
         <value>廊坊師院</value>
      </constructor-arg>

   構造器中一個引數,則索引值是從0開始,若是有多個,依次遞增。

    若構造器中的是一個類,則使用bean標籤

   <constructor-arg index="0">

    <bean class="具體的類">

  </constructor-arg>

   PS:當再次看部落格,有了新的感觸。2012年8月7日 15:06:52

   spring中的依賴注入DI(dependence injection)共有三種方式:第一種是介面注入(Interface Injection)第二種是get set注入(set/get Injection)第三種是構造器注入(Constructor Injection)

   三種注入方式的區別:

   1.介面注入:元件需要依賴特定介面的實現,其中的載入介面實現和介面實現的具體物件都是由容器來完成。這樣,介面必須依賴容器,這樣的元件具有侵入性,降低了重用性。其中如J2EE開發中常用的Context.lookup(ServletContext.getXXX),都是介面注入的表現形式。(這種注入方式不是常用的)

   2.getter/setter方式注入:對於需要注入的東西比較明確。符合java的設計規則。更適合java開發人員,使用起來更加自然,更加方便。

   3.構造器方式注入:在類載入的時候,就已經注入依賴的元件。但是若是引數多的話,使用起來不方便。

  但是後兩種注入方式是spring常用的,而第一種介面注入方式不常用。