Closed
Description
Affects: 5.3.3
We use an AsyncConfigurer
that needs some beans. Spring wants to create a BeanPostProcessor asyncAdvisor
at
org.springframework.scheduling.annotation.ProxyAsyncConfiguration
. This bean post processor uses the instance variables this.executor
and this.exceptionHandler
all AsyncConfigurer are autowired to ProxyAsyncConfiguration via the following method
org.springframework.scheduling.annotation.AbstractAsyncConfiguration
@Autowired(required = false)
void setConfigurers(Collection<AsyncConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
AsyncConfigurer configurer = configurers.iterator().next();
this.executor = configurer::getAsyncExecutor;
this.exceptionHandler = configurer::getAsyncUncaughtExceptionHandler;
}
This leads to a prelimary instance creation of all asyncConfigurer and its dependent beans.
IMHO this should be changed to use an ObjectProvider instead:
protected ObjectProvider<AsyncConfigurer> configurersProvider;
@Autowired(required = false)
void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
this.configurersProvider = configurers;
}
protected void evaluateAsyncConfigurer() {
List<AsyncConfigurer> configurers = configurersProvider.orderedStream().collect(Collectors.toList());
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
AsyncConfigurer configurer = configurers.iterator().next();
this.executor = configurer::getAsyncExecutor;
this.exceptionHandler = configurer::getAsyncUncaughtExceptionHandler;
}
method evaluateAsyncConfigurer() should be called before access to this.executor and this.exceptionHandler in child classes.