2013-03-21 90 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这是特别有帮助。