基于构造函数的依赖注入



当容器调用一个类构造函数,该构造函数包含多个参数,每个参数代表对其他类的依赖时,就会实现基于构造函数的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
广告