2016-06-28 108 views
12

我在春季有一個關於自動佈線訂單和@PostConstruct邏輯的問題。例如下面的演示代碼,我有一個主彈簧引導類:春季自動裝配訂單和@PostConstruct

@SpringBootApplication 
public class Demo1Application { 

    @Autowired 
    BeanB beanb; 

    public static void main(String[] args) { 
     SpringApplication.run(Demo1Application.class, args); 
    } 
} 

和2 @Service定義:

@Service 
public class BeanB { 

    @Autowired 
    private BeanA beana ; 

    @PostConstruct 
    public void init(){ 
     System.out.println("beanb is called"); 
    } 

    public void printMe(){ 
     System.out.println("print me is called in Bean B"); 
    } 
} 

@Service 
public class BeanA { 

    @Autowired 
    private BeanB b; 

    @PostConstruct 
    public void init(){ 
     System.out.println("bean a is called"); 
     b.printMe(); 
    } 
} 

,我有以下的輸出:

豆被稱爲

打印我在Bean B中調用

beanb被稱爲


我的問題是自動裝配是如何發生的一步一步像上面的​​場景?
以及如何printMe()方法beanb被調用,而不是先調用其@PostConstruct

回答

8

下面應該是可能的序列

  1. beanb開始變得自動連接
  2. 期間Beanb類的初始化,beana開始被自動連接
  3. 一旦beana被創建beana的@PostConstructinit()被稱爲
  4. Inside init()System.out.println("bean a is called");被稱爲
  5. 然後b.printMe();被調用導致System.out.println("print me is called in Bean B");執行
  6. 具有beana完成@PostConstructbeanbinit()被調用
  7. 然後System.out.println("beanb is called");被調用

在理想情況下同樣可以通過在蝕調試器可更好地觀察到的。

Spring reference manual說明如何解決循環依賴關係。這些bean首先被實例化,然後被注入彼此。

+1

[鏈接](https://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/beans。 html#beans-dependency-resolution)到循環依賴解析。 –

3

你的答案是正確的,正如你在你的問題中所示。

現在獲取符號的概念@Autowired。全部@Autowired對象初始化並在類加載完成後加載到內存中。

現在,這裏是你的SpringBootApplication

@SpringBootApplication 
public class Demo1Application { 
    @Autowired 
    BeanB beanb; // You are trying to autowire a Bean class Named BeanB. 

在這裏,在上述控制檯應用程序,你必須寫嘗試自動裝配和注入BeanB類型的對象。

現在,這裏是你的BeanB

@Service 
public class BeanB { 

    @Autowired 
    private BeanA beana ; 

BeanB類,你正在試圖注入這也是在您的控制檯項目中定義BeanA類的對象定義。

因此,在您的Demo1Application中注入類BeanB的對象必須注入類BeanA的對象。 Now BeanA類對象首先被創建。

現在,如果你看到你的類BeanA

@Service 
public class BeanA { 

    @Autowired 
    private BeanB b; 

    @PostConstruct // after Creating bean init() will be execute. 
    public void init(){ 
     System.out.println("bean a is called"); 
     b.printMe(); 
    } 
} 

這樣的定義,@PostContruct註釋是要執行注射對象BeanA方法綁定後。

所以,執行流程將..

System.out.println("bean a is called"); 
System.out.println("print me is called in Bean B"); 
System.out.println("beanb is called");