Java Spring Beans中constructor-arg中的ref有什么用处?

7

我对Spring Bean还不熟悉,所以不理解在constructor-arg中使用ref的作用。为什么不能像这个例子一样再次使用value呢?

以下是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>

为什么不采用这种方式,直接使用spellChecker bean,而不是创建一个文本编辑器bean并引用另一个对象spellChecker?

在MainApp.java中

TextEditor te = (TextEditor) context.getBean("spellChecker");

如果我们使用它是因为两个对象属于不同的类,那么如果两个对象属于同一个类,我们可以省略ref吗?

另外,如果多个对象引用同一个对象,是必须为每个类创建一个bean并使用ref引用该对象,还是使用相同的bean但其scope=prototype?


你是不是想说 SpellChecker sc = (SpellChecker) context.getBean("spellChecker"); 而不是 TextEditor te = (TextEditor) context.getBean("spellChecker");?在你的例子中,TextEditor 除了将任务委托给 SpellChecker 外并没有做太多事情。然而,在一个真实的应用程序中,它会有更多的责任。 - asgs
2个回答

3
Spring bean的ref属性引用了在其他地方实例化的另一个Spring Bean。在您的情况下,SpellChecker是一个Spring单例Bean,您想要将其“注入”到另一个类型为TextEditor的Spring Bean中。使用ref的原因是,除非您希望它们按请求、会话等方式创建,否则大多数Bean都将是单例的。默认范围是Singleton。

此外,如果多个对象引用同一个对象,是否需要为每个类创建一个bean并使用ref引用该对象,或者使用相同的bean但scope=prototype?

我认为您想说“多个类引用同一个对象”。在这种情况下,您在类中所做的全部工作就是声明对该bean(或对象)的“引用”。然后,您将该bean“注入”到依赖的类(或bean)中。

您可以阅读更多关于Spring Bean引用的内容。


0

如果多个对象引用同一对象,是否需要为每个类创建一个bean并使用ref引用该对象,还是使用相同的bean但scope=prototype?

如果多个类引用同一对象,则可以使用单例作用域(如果您不在bean中指定作用域属性,则默认为单例)。在单例中,多个对象共享单例对象。它们只创建对单例对象的本地引用。它们不会每次初始化新对象。因此,不会使用太多堆内存。

而在原型中,每个对象都会创建一个新的内部对象(即在本地初始化新对象引用)。因此,创建许多对象会产生开销,结果是堆被加载。

完全取决于您的应用程序要使用哪种范围。但通常,在Web应用程序中,人们使用Singleton来处理DAO连接类,以便连接过程仅发生一次,并由引用DAOConnection类的所有类重复使用。

他们使用原型来处理POJO类。这样,每次类引用它时都会创建一个新对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接