依赖注入如何在没有构造函数的情况下实例化一个类?

时间:2015-10-25 17:49:08

标签: java spring dependency-injection

我遵循以下依赖注入示例:http://www.tutorialspoint.com/spring/spring_autowired_annotation.htm

例如TextEditor类(来自上面的链接):

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   public SpellChecker getSpellChecker( ) {
      return spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

这些依赖项/类如何实例化,而它们没有任何构造函数?

Java只是制作那种类型的对象,那是空的吗?就像没有任何代码的空参数构造函数一样?

感谢您让这一点更加清晰!

3 个答案:

答案 0 :(得分:3)

除非另有说明,否则每个Java类都有默认构造函数。所以在这里,你有一个默认的public TextEditor()构造函数,即使你没有为它编码。 (如果您需要从公共场所更改其可见性,声明抛出的异常等,则可以对其进行编码。)

所以是的,Spring调用这个默认构造函数 - 然后调用setSpellChecker方法(注释,并通过反射)来填充它。

答案 1 :(得分:2)

如果没有定义构造函数,则可以通过无参数默认构造函数实例化一个类。

因此,框架调用该构造函数(假设使用反射),然后使用set方法设置新创建的类的一个字段。

答案 2 :(得分:2)

上面的例子是使用Spring注释和Spring上下文文件,考虑到DI,这些是项目的主要和最重要的部分。

因此,在上下文文件中,您有以下行:

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

这定义了一个引用spellChecker的类,它可以映射到类com.tutorialspoint.SpellChecker,并且一旦编译器在一个方法中找到这样的属性,该方法在它注入的对象的实例化时被标记为@Autowired /设置所需依赖项的相关版本。

如果属性与applicationContext.xml文件中的引用标记不匹配,Spring会尝试映射类型,例如名称为mySpecialSpellChecker且属性为com.tutorialspoint.SpellChecker的属性仍将映射到带有id="spellChecker"的bean,如果有多个相同类型的Spring将不会实例化您的对象,您可能会得到编译时错误,因为Spring无法知道两个(或更多)的哪个版本是正确的,所以这需要开发人员输入。

这是执行的顺序:

  1. 实例化textEditor,这个默认构造函数在代码public TextEditor ()中不可见
  2. 新实例在可用对象池中设置,引用为textEditor
  3. 实例化spellChecker并添加到具有相关参考/标签的可用对象池
  4. 使用相关对象设置/调用所有@Autowired属性/方法,在这种情况下,Spring调用:setSpellChecker(spellChecker)