基於建構函式的依賴注入



當容器呼叫一個類建構函式,該建構函式包含多個引數,每個引數代表對其他類的依賴時,就會實現基於建構函式的DI。

示例

以下示例顯示了一個TextEditor類,它只能透過建構函式注入進行依賴注入。

讓我們準備好一個可執行的Eclipse IDE,並按照以下步驟建立一個Spring應用程式:

步驟 描述
1 建立一個名為SpringExample的專案,並在建立的專案中src資料夾下建立一個包com.tutorialspoint
2 使用新增外部JAR選項新增所需的Spring庫,如Spring Hello World示例章節中所述。
3 com.tutorialspoint包下建立Java類TextEditorSpellCheckerMainApp
4 src資料夾下建立Beans配置檔案Beans.xml
5 最後一步是建立所有Java檔案和Bean配置檔案的內容,並按如下所述執行應用程式。

以下是TextEditor.java檔案的內容:

package com.tutorialspoint;

public class TextEditor {
   private SpellChecker spellChecker;

   public TextEditor(SpellChecker spellChecker) {
      System.out.println("Inside TextEditor constructor." );
      this.spellChecker = spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

以下是另一個依賴類檔案SpellChecker.java的內容:

package com.tutorialspoint;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   }
}

以下是MainApp.java檔案的內容:

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      TextEditor te = (TextEditor) context.getBean("textEditor");
      te.spellCheck();
   }
}

以下是具有基於建構函式注入配置的配置檔案Beans.xml

<?xml version = "1.0" encoding = "UTF-8"?>

<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.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id = "textEditor" class = "com.tutorialspoint.TextEditor">
      <constructor-arg ref = "spellChecker"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"></bean>

</beans>

建立原始檔和Bean配置檔案後,讓我們執行應用程式。如果您的應用程式一切正常,它將列印以下訊息:

Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.

建構函式引數解析

如果有多個引數,傳遞引數到建構函式時可能會出現歧義。為了解決這種歧義,bean定義中建構函式引數的定義順序就是這些引數提供給相應建構函式的順序。考慮以下類:

package x.y;

public class Foo {
   public Foo(Bar bar, Baz baz) {
      // ...
   }
}

以下配置可以正常工作:

<beans>
   <bean id = "foo" class = "x.y.Foo">
      <constructor-arg ref = "bar"/>
      <constructor-arg ref = "baz"/>
   </bean>

   <bean id = "bar" class = "x.y.Bar"/>
   <bean id = "baz" class = "x.y.Baz"/>
</beans>

讓我們檢查一下另一個情況,我們將不同型別傳遞給建構函式。考慮以下類:

package x.y;

public class Foo {
   public Foo(int year, String name) {
      // ...
   }
}

如果您使用type屬性顯式指定建構函式引數的型別,則容器也可以對簡單型別使用型別匹配。例如:

<beans>

   <bean id = "exampleBean" class = "examples.ExampleBean">
      <constructor-arg type = "int" value = "2001"/>
      <constructor-arg type = "java.lang.String" value = "Zara"/>
   </bean>

</beans>

最後,傳遞建構函式引數的最佳方法是使用index屬性顯式指定建構函式引數的索引。這裡,索引是基於0的。例如:

<beans>

   <bean id = "exampleBean" class = "examples.ExampleBean">
      <constructor-arg index = "0" value = "2001"/>
      <constructor-arg index = "1" value = "Zara"/>
   </bean>

</beans>

最後一點,如果您正在傳遞對物件的引用,則需要使用<constructor-arg>標籤的ref屬性;如果您直接傳遞值,則應使用上面所示的value屬性。

spring_dependency_injection.htm
廣告
© . All rights reserved.