【问题标题】:@Autowired and bean creation order@Autowired 和 bean 创建顺序
【发布时间】:2013-03-21 21:19:07
【问题描述】:

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

我有一个FactoryBean,它创建一个类型为A 的对象,该对象具有一个名为a 的属性。如果属性为空,它会为 bean A 分配一个默认值。

在@Configuration 类中我有:

@自动连线 私有的一个 myBean;

发生的事情是工厂创建了 bean(我不完全理解如何)但是工厂中的字段 a 为空,我需要它需要另一个它习惯的 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 的建议修复它包装工厂

【问题讨论】:

  • 请展示您的工厂如何创建您的 bean,例如。 &lt;bean&gt; 声明

标签: java spring autowired


【解决方案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"/>

【讨论】:

  • 其实这个问题有点棘手,并没有显示在问题中。问题是由于 A 正在实现 ApplicationListener 并且工厂正在报告应用程序事件而导致的循环引用。因此,A 被注册为创建 A 的工厂的侦听器。无论如何@emd 响应帮助我理解了问题
【解决方案2】:

根据您的问题,我假设 @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,这将特别有用。

【讨论】:

    猜你喜欢
    • 2018-06-26
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 2019-04-03
    • 1970-01-01
    • 2016-03-14
    相关资源
    最近更新 更多