Spring的核心機制:依賴注入

 

依賴注入的概念

當一個對象要調用另外一個對象時,通常是new一個被調用的對象,示例:app

class  A{ide

  private B b=new B();函數

  public  void  test(){測試

    b.say();this

  }spa

}code

A類的對象依賴於B類對象,若是沒有B類對象,A類對象就不能正常工做,稱A依賴於B。xml

以上方式會增長類A與類B的耦合性,不利於項目後期的升級(擴展)、維護。對象

 

在Spring中,B類的實例(被調用者),再也不由A類(調用者)建立,而是由Spring容器建立,建立好之後,由Spring容器將B類的實例注入A類對象中,稱爲依賴注入(Dependency Injection,DI)。blog

本來是由A類主動建立B類對象(A類控制B類的建立),如今是Spring容器建立B類對象,注入A類對象中,A類被動接受Spring容器建立的B類實例,B類對象建立的控制權發生了反轉,因此又叫作控制反轉(Inversion of Control,IoC)。

 

依賴注入是一種優秀的解耦方式,由Spring容器負責控制類(Bean)之間的關係,下降了類之間的耦合。

由於Spring容器負責依賴注入(IoC),因此Spring容器也被稱爲Spring IoC容器。

 

依賴注入有2種實現方式:

  • 設值注入
  • 構造注入

 

 

 

 

設值注入

經過主調類的setter()方法注入被調類的實例。一個參數即一個依賴對象。

 

一、分別寫2個接口

1 public interface Student {
2     public String getName();
3 }
1 public interface Teacher {
2     public void say();
3 }

 

 

二、分別寫2個實現類

 1 public class BadStudent implements Student {
 2     private String name;
 3 
 4     public BadStudent(String name){
 5         this.name=name;
 6     }
 7 
 8     @Override
 9     public String getName(){
10         return name;
11     }
12 }
 1 public class MathTeacher implements Teacher{
 2     private Student student;
 3 
 4     //主調者的setter()方法,接受被調者實例
 5     public void setStudent(Student student){
 6         this.student=student;
 7     }
 8 
 9     @Override
10     public void say() {
11         System.out.println(student.getName()+",叫家長來一下。");
12     }
13 }

 類與接口耦合。

 

 

三、在applicationContext.xml文件中配置Bean

1 <!-- 初始化BadStudent類的實例lisi-->
2     <bean name="lisi" class="beans.BadStudent">
3         <constructor-arg value="李四" />  <!--向BadStudent的構造函數傳遞」李四「-->
4     </bean>
5 
6     <!--配置依賴-->
7     <bean name="mathTeacher" class="beans.MathTeacher">
8         <property name="student" ref="lisi" />  <!--name指定setter方法的形參,ref或者value指定實參:某個Bean的name-->
9     </bean>

 

 <constructor-arg>元素向該Bean的構造函數傳遞實參,一個<constructor-arg>傳遞一個實參,一個<bean>可配置多個<constructor-arg>,根據傳遞的實參個數來調用相應的構造函數。constructor-arg即構造器參數。

實參值經過value或ref屬性來指定。value指定的是Java基礎類型的參數,ref即reference(引用),指定依賴的其它Bean。

可經過屬性index指定該value是第幾個參數,默認從0自動遞增。

 

 

<property>屬性指定setter方法的實參。一個<property>指定一個參數,一個<bean>可帶有多個<property>子元素。

name屬性指定setter方法中的某個形參,實參由value或ref指定。

若是實參是某個Bean的實例,用ref指定,值是該Bean的name屬性值。

若是實參是Java的基礎類型(整型、浮點型、String等),用value指定(放在引號中),Spring容器會自動根據name的指定形參的類型,將實參轉換爲相應的類型進行賦值。

 

 

四、寫一個測試類

1 public class Test {
2     public static void main(String[] args) {
3         ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
4         MathTeacher mathTeacher=applicationContext.getBean("mathTeacher",MathTeacher.class);
5         mathTeacher.say();
6     }
7 }

 看到控制檯已經打印出了「李四,叫家長來一下。」。

 

 

 

 

 

構造注入

經過構造函數注入。

一、上面的代碼,將MathTeacher類修改以下

 1 public class MathTeacher implements Teacher{
 2     private Student student;
 3 
 4     //主調者的構造方法 5 public MathTeacher(Student student){ 6 this.student=student; 7 }  8 
 9     @Override
10     public void say() {
11         System.out.println(student.getName()+",叫家長來一下。");
12     }
13 }

不使用setter方法注入依賴的對象,而是使用構造函數注入依賴的對象。

 

二、修改Spring容器的配置以下

1  <!-- 初始化BadStudent類的實例lisi-->
2     <bean name="lisi" class="beans.BadStudent">
3         <constructor-arg value="李四" />
4     </bean>
5 
6 <!--配置依賴--> 7 <bean name="mathTeacher" class="beans.MathTeacher"> 8 <constructor-arg name="student" ref="lisi" /> 9 </bean>

 

三、運行,看到控制檯打印出「李四,叫家長來一下。」。

 

 

 

說明

  • 這兩種方式均可以注入Java的自帶的數據類型。
  • value是注入Java的基礎類型,ref是注入依賴的Bean。固然也能夠用<value>、<ref>子元素的形式配置。

相關文章
相關標籤/搜索