当Java Config实现AsyncConfigurer时,@ Resource会变为null

时间:2014-04-23 21:43:59

标签: spring spring-java-config

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

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

当我在构造方法上设置调试器时,我可以看到bean实际上是null。它似乎是某种竞争条件,因为在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;
    }
}

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

根据documentation

  

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

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

2 个答案:

答案 0 :(得分:1)

您的backgroundProcessor bean似乎取决于您的6个资源bean。

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

@Bean(name="backgroundProcessor")
@DependsOn("bean1","bean2","bean3","bean4","bean5","bean6")
public BackgroundProcessor getBackgroundProcessor() {..}

答案 1 :(得分: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;
    }
}

然后将@Resource注释添加到BackgroundProcessor类:

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

出于某种原因,这种方法很好。我不喜欢这个,因为我更喜欢我的课程不依赖于IOC注释,但我现在将使用这个解决方案。