1

我有一个非常奇怪的问题。我正在使用 Spring 3.2.4 并且有一个 Spring Java Config 类,它是 Java 和 XML 配置文件的更大组合的一部分。

该文件使用其他配置文件中定义的 6 个资源来构造 @Async bean。当我将“实现 AsyncConfigurer”添加到文件中时,一些 @Resource 字段显示为空,但是当我关闭实现时,它们会被填充。这很令人困惑,因为 AsyncConfigurer 只是用来配置你的异步执行器,它不应该做任何时髦的事情,比如导致你的配置被异步加载。

当我在构造方法上设置调试器时,我可以看到这些 bean 实际上是空的。这似乎是某种竞争条件,因为在 6 个 bean 中,第 4 个曾经为空,然后在下一次填充。

我的文件看起来像:

public class UserBackgroundProcessorConfiguration implements AsyncConfigurer {

    @Resource(name="bean1")
    MyBean bean1;

    // in reality there are 6 @Resources defined...

    @Resource(name="bean6")
    MyBean bean6;

    @Bean(name="backgroundProcessor")
    public BackgroundProcessor getBackgroundProcessor() {
        BackgroundProcessor backgroundProcess = new BackgroundProcessor();
        backgroundProcess.setBean1(bean1);
        // beans 1-3 are always populated
        // bean 4 seems to sometimes be populated, sometimes null
        // beans 5&6 are always null
        backgroundProcess.setBean6(bean6);

        return backgroundProcess;
    }

    @Override
    @Bean(name="executor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(40);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("BackgroundProcessor-");
        return executor;
    }
}

同样,当我删除“实现 AsyncConfigurer”并注释掉 getAsyncExecutor 时,问题就消失了。

根据文档

由带有 @EnableAsync 注释的 @Configuration 类实现的接口,这些类希望自定义处理异步方法调用时使用的 Executor 实例。

所以我不明白这是如何导致我所看到的行为的。

4

2 回答 2

1

看来您的backgroundProcessorbean 取决于您的 6 个资源 bean。

尝试使用以下方法注释方法签名:

@Bean(name="backgroundProcessor")
@DependsOn("bean1","bean2","bean3","bean4","bean5","bean6")
public BackgroundProcessor getBackgroundProcessor() {..}
于 2014-04-23T22:11:16.887 回答
1

我通过从 Java 配置文件中删除@Resource 注释解决了这个问题:

public class UserBackgroundProcessorConfiguration implements AsyncConfigurer {

    @Bean(name="backgroundProcessor")
    public BackgroundProcessor getBackgroundProcessor() {
        BackgroundProcessor backgroundProcess = new BackgroundProcessor();
        return backgroundProcess;
    }

    @Override
    @Bean(name="executor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(40);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("BackgroundProcessor-");
        return executor;
    }
}

然后在 BackgroundProcessor 类中添加@Resource 注解:

public class BackgroundProcessor {
    @Resource private MyBean bean1;
    // 4 more
    @Resource private MyBean bean6;
}

出于某种原因,这很好用。我不太喜欢这个,因为我希望我的类不依赖于 IOC 注释,但我现在会使用这个解决方案。

于 2014-04-24T17:30:53.050 回答