Skip to content

Commit de10bb6

Browse files
committed
Stop resolving AsyncConfigurer instances eagerly
Closes gh-27808
1 parent c764242 commit de10bb6

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,18 +16,22 @@
1616

1717
package org.springframework.scheduling.annotation;
1818

19-
import java.util.Collection;
19+
import java.util.List;
2020
import java.util.concurrent.Executor;
21+
import java.util.function.Function;
2122
import java.util.function.Supplier;
23+
import java.util.stream.Collectors;
2224

2325
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
26+
import org.springframework.beans.factory.ObjectProvider;
2427
import org.springframework.beans.factory.annotation.Autowired;
2528
import org.springframework.context.annotation.Configuration;
2629
import org.springframework.context.annotation.ImportAware;
2730
import org.springframework.core.annotation.AnnotationAttributes;
2831
import org.springframework.core.type.AnnotationMetadata;
2932
import org.springframework.lang.Nullable;
3033
import org.springframework.util.CollectionUtils;
34+
import org.springframework.util.function.SingletonSupplier;
3135

3236
/**
3337
* Abstract base {@code Configuration} class providing common structure for enabling
@@ -65,17 +69,27 @@ public void setImportMetadata(AnnotationMetadata importMetadata) {
6569
/**
6670
* Collect any {@link AsyncConfigurer} beans through autowiring.
6771
*/
68-
@Autowired(required = false)
69-
void setConfigurers(Collection<AsyncConfigurer> configurers) {
70-
if (CollectionUtils.isEmpty(configurers)) {
71-
return;
72-
}
73-
if (configurers.size() > 1) {
74-
throw new IllegalStateException("Only one AsyncConfigurer may exist");
75-
}
76-
AsyncConfigurer configurer = configurers.iterator().next();
77-
this.executor = configurer::getAsyncExecutor;
78-
this.exceptionHandler = configurer::getAsyncUncaughtExceptionHandler;
72+
@Autowired
73+
void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
74+
Supplier<AsyncConfigurer> asyncConfigurer = SingletonSupplier.of(() -> {
75+
List<AsyncConfigurer> candidates = configurers.stream().collect(Collectors.toList());
76+
if (CollectionUtils.isEmpty(candidates)) {
77+
return null;
78+
}
79+
if (candidates.size() > 1) {
80+
throw new IllegalStateException("Only one AsyncConfigurer may exist");
81+
}
82+
return candidates.get(0);
83+
});
84+
this.executor = adapt(asyncConfigurer, AsyncConfigurer::getAsyncExecutor);
85+
this.exceptionHandler = adapt(asyncConfigurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
86+
}
87+
88+
private <T> Supplier<T> adapt(Supplier<AsyncConfigurer> supplier, Function<AsyncConfigurer, T> provider) {
89+
return () -> {
90+
AsyncConfigurer asyncConfigurer = supplier.get();
91+
return (asyncConfigurer != null) ? provider.apply(asyncConfigurer) : null;
92+
};
7993
}
8094

8195
}

0 commit comments

Comments
 (0)