2013-03-21 498 views
3

是否有可能避免@Autowire一些bean,直到其他depeandant bean被創建?讓我用一個例子更好地解釋它:@Autowired和bean創建順序

我有一個創建類型一個有一個名爲一個屬性的對象一個FactoryBean。如果該屬性爲空,則爲該豆分配默認值A

在@Configuration I類有:

 

    @Autowired 
    private A myBean; 

正在發生的事情是,工廠創建bean(我不完全瞭解),但場在工廠是零和我需要它需要另一個豆,它用於創建A。由於它在外部依賴關係中,因此我無法向Factory添加任何註釋。

事情是,我需要在@Autowired請求對象到工廠之前設置值a。有沒有可能給我的限制?

編輯 繼承人的代碼:

@Configuration 
@ImportResource("classpath:factory-context.xml") 
public class ServiceContextConfig { 
    @Autowired 
    private A createdObject; 

    @Bean(name = "entities-list") 
    public List<String> getEntity() { 
     List<String> ls = new ArrayList<String>(); 
     ls.add("countriescatalog"); 
     return ls; 
    } 

然後工廠的context.xml看起來是這樣的:

<bean id="client-factory" class="ClientFactory"> 
    <property name="entities" ref="entities-list"/> 
</bean> 

其實配置是有點大。我沒有嘗試用這樣的簡單例子。我會嘗試重現它與這樣一個簡單的上下文,看看我是否可以修復它包裝工廠作爲@emd建議

+0

請顯示您的工廠如何創建您的bean,例如。 ''聲明 – 2013-03-21 21:26:39

回答

1

我希望我明白了這個問題的權利。但這裏有一個例子,你可以做什麼:

包裝工廠在你自己的工廠。在你自己的工廠自動裝配該領域。用原始工廠構造對象,注入字段並返回對象。

例子:

public class MyFactory { 

    @Autowired 
    private A a; 

    private final OriginalFactory originalFactory; 

    public MyFactory(OriginalFactory originalFactory) { 
     this.originalFactory=originalFactory; 
    } 

    public CreateObject getInstance() { 

     CreatedObject createdObject = originalFactory.getInstance(); 
     createdObject.setA(a); 

     return createdObject; 
    } 
} 

彈簧部:

<bean id="myFactory" class="aa.aa.MyFactory"> 
    <constructor-arg ref="originalFactory" /> 
</bean>   
<bean id="createdObject" factory-bean="myFactory" factory-method="getInstance"/> 
+0

其實問題有點棘手,並沒有在問題中顯示。問題是由於A正在實現ApplicationListener而導致的循環引用,並且工廠正在報告應用程序事件。所以A被註冊爲正在創建A的工廠的監聽器。無論如何@emd響應幫助我理解了這個問題 – gfournier 2013-03-27 19:53:05

0

根據你的問題,我假設@Autowired A createdObject取決於@Bean "entities-list",但"entities-list"已創建前createdObject被自動裝配。

我遇到了類似的問題,並找到了解決方案。

在任何特定@Configuration類中,Spring在將任何@Bean方法添加到上下文之前首先會解析所有@Autowired字段。但是,在解決@Autowired字段之前,@Import列表中的任何bean都將添加到上下文中。

因此,我們可以解決我們的問題,通過創建一個內部配置類:

@Configuration 
@Import(ServiceContextConfig.InnerConfig.class) // <-- don't forget to add here 
@ImportResource("classpath:factory-context.xml") 
public class ServiceContextConfig { 
    @Autowired 
    private A createdObject; 

    @Configuration 
    static class InnerConfig {  // <-- wrap bean in an "inner-configuration" 
     @Bean(name = "entities-list") 
     public List<String> getEntity() { 
      List<String> ls = new ArrayList<String>(); 
      ls.add("countriescatalog"); 
      return ls; 
     } 
    } 
} 

如果無法編輯其他配置,factory-context.xml這是特別有幫助。