@Autowired和bean创建顺序

时间:2013-03-21 21:19:08

标签: java spring autowired

在创建其他依赖bean之前,是否可以避免@Autowire一些bean?让我用一个例子更好地解释一下:

我有一个FactoryBean,它创建一个 A 类型的对象,该对象具有一个名为 a 的属性。如果该属性为null,则为bean A

分配一个默认值

在@Configuration类中,我有:


    @Autowired
    private A myBean;

正在发生的是工厂创建bean(我不完全理解如何)但是工厂中的 a 字段为null,我需要它需要另一个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;
    }

然后factory-context.xml如下所示:

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

实际上配置有点大。我没有尝试这样的简化示例。我将尝试使用这样的简化上下文重现它,看看我是否可以修复它包装工厂@emd建议

2 个答案:

答案 0 :(得分: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"/>

答案 1 :(得分:0)

根据您的问题,我假设@Autowired A createdObject取决于@Bean "entities-list",但createdObject在创建"entities-list"之前正在自动装配。

我遇到了类似的问题并找到了解决方案。

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

因此,我们可以通过创建内部配置类来解决我们的问题:

@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

,这将特别有用