2016-11-11 108 views
2

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

ClassA的

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; 
    } 

} 

ClassB的

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

ClassC

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(); 
    } 
} 

豆配置文件是

?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 
+0

太宽泛。你到底迷惑了什么? – Andrew

+0

为什么你多次映射com.example.ClassD,即objectC&others? – developer

+0

我无法理解该程序输出的顺序?我认为在输出的第三行中必须有“构造classB对象”,但结果显示“有正在构建的classD对象” –

回答

3

的示例以及演示单之间的差原型示波器。

第一个实例将立即创建并且IOC控制器应支持其整个生命周期。

与此相反的单身,为原型范围,容器将由我们的需求创建一个实例。一个请求 - 创建一个来自上下文的新的配置良好的对象。一个容器不会照顾这种类型的豆子,因为它们在放弃后不再考虑它们。

简单地说,让我们通过每个语句:

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

关于延迟初始化:

有两个ClassD单身人士和可能,他们应该通过启动一个容器被初始化,但最后他们都标有lazy-init="false"这可以防止这种行为。顺便说一下,这不是一个推荐的做法,因为编译时的错误检测总是比在运行时检测它们好。

+0

我得到了我的答案。非常感谢你 。 –