我有一个非常奇怪的问题。我使用的是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时,问题就消失了。
由@EnableAsync注释的@Configuration类实现的接口,希望自定义处理异步方法调用时使用的Executor实例。
所以我不明白这是怎么导致我看到的行为。
答案 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注释,但我现在将使用这个解决方案。