【问题标题】:Spring bean order of executionSpring bean的执行顺序
【发布时间】:2016-11-11 21:54:39
【问题描述】:

我有以下类,主类和 bean 配置文件。程序的结果也给出了。我的问题是我不知道如何获得此输出?我不明白这个程序给出输出的顺序。我认为在输出的第三行中必须有“正在构建 classB 对象”,但结果显示“正在构建 classD 对象”。

A类

public abstract class ClassA {
    private String text;

    public ClassA(){
        System.out.println("- new -");
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

}

B类

public class ClassB extends ClassA {
    public void settings(){
        System.out.println("Constructing ClassB object");
    }
}

C类

public class ClassC {
    private List<ClassA> items = new ArrayList<>();

    public List<ClassA> getItems(){
        return items;
    }

    public void setItems(List<ClassA> items) {
        this.items = items;
    }

    public void print(){
        String s = "This object contains: ";
        for(ClassA item : items){
            s+= item.getText();
        }
        System.out.println(s);
    }
}

D类

public class ClassD extends ClassA {
    public void settings(){
        System.out.println("Constructing ClassD Object");
    }
}

主要方法是

public class Question1Application {

    public static void main(String[] args) {
        //SpringApplication.run(Question1Application.class, args);
        System.out.println("PREPARE");
        ConfigurableApplicationContext context = new      ClassPathXmlApplicationContext("springconfig.xml");
        System.out.println("BEGIN");
        ClassB classB = context.getBean("objectB",ClassB.class);
        ClassC classC = context.getBean("objectF",ClassC.class);
        System.out.println("END");
        context.close();
    }
}

Bean配置文件是

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

<bean id="objectA" class="com.example.ClassA" abstract="true">
    <property name="text" value="Things!"></property>
</bean>

<bean id="objectB" class="com.example.ClassB" scope="prototype" parent="objectA"
    init-method="settings">
</bean>

<bean id="objectC" class="com.example.ClassD" scope="prototype" parent="objectA"
    init-method="settings">
</bean>

<bean id="objectD" class="com.example.ClassD" lazy-init="true" parent="objectA"
    init-method="settings">
</bean>

<bean id="objectE" class="com.example.ClassD" parent="objectA" init-method="settings"></bean>

<bean id="objectF" class="com.example.ClassC" init-method="print">
    <property name="items">
        <list>
            <ref bean="objectB"></ref>
            <bean class="com.example.ClassB">
                <property name="text" value="lot of things!"></property>
            </bean>
        </list>
    </property>
</bean>

程序的输出是:

PREPARE
-new-
constructing classD object
-new-
constructing classB object
-new-
This object contains : lots of things!
BEGIN
-new-
constructing classB object
END

【问题讨论】:

  • 太宽泛了。你到底对什么感到困惑?
  • 你为什么要多次映射 com.example.ClassD ,即为 objectC 和其他?
  • 我无法理解这个程序给出输出的顺序?我认为在输出的第三行中必须有“正在构建 classB 对象”,但结果显示“正在构建 classD 对象”
  • 我知道单例创建单个对象并为所有对象提供相同的对象引用,但在原型的情况下,它会在需要时创建新对象。
  • 你为什么期待“构造B类对象”?你能说出你的理由然后我可以回答

标签: java spring


【解决方案1】:

这个例子很好地展示了 singletonprototype 作用域之间的区别。

第一个实例的创建会立即启动上下文,并且 IOC 控制器应该支持它们的整个生命周期。

singletons 相比,对于 prototype 范围,容器将根据我们的需求创建一个实例。一个请求 - 从上下文中创建一个配置良好的新对象。容器不会照顾这种类型的豆子在赠送后停止考虑它们。

简单来说,让我们来看看每一条语句:

  1. PREPARE - 上下文启动 - singleton 初始化的开始
  2. constructing classD object - 这是一个单身人士
  3. constructing classB object - objectF 是一个单例,需要创建一个 ClassB 实例来初始化它
  4. BEGIN - 所有单例都被引导
  5. constructing classB object - 由于context.getBean("objectB",ClassB.class);

关于延迟初始化:

有两个 ClassD 单例,它们可能应该在启动时由容器初始化,但最后一个标有 lazy-init="false" 以防止此类行为。顺便说一句,这不是推荐的做法,因为在编译时检测错误总是比在运行时检测它们好。

【讨论】:

  • 我得到了答案。非常感谢。
猜你喜欢
  • 2016-07-05
  • 2015-04-15
  • 2015-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 2019-12-25
  • 2017-04-23
  • 1970-01-01
相关资源
最近更新 更多