2016-11-11 68 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

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