|  | 
| 1 | 1 | /* | 
| 2 |  | - * Copyright 2002-2020 the original author or authors. | 
|  | 2 | + * Copyright 2002-2021 the original author or authors. | 
| 3 | 3 |  * | 
| 4 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
| 5 | 5 |  * you may not use this file except in compliance with the License. | 
|  | 
| 16 | 16 | 
 | 
| 17 | 17 | package org.springframework.scheduling.annotation; | 
| 18 | 18 | 
 | 
| 19 |  | -import java.util.Collection; | 
|  | 19 | +import java.util.List; | 
| 20 | 20 | import java.util.concurrent.Executor; | 
|  | 21 | +import java.util.function.Function; | 
| 21 | 22 | import java.util.function.Supplier; | 
|  | 23 | +import java.util.stream.Collectors; | 
| 22 | 24 | 
 | 
| 23 | 25 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; | 
|  | 26 | +import org.springframework.beans.factory.ObjectProvider; | 
| 24 | 27 | import org.springframework.beans.factory.annotation.Autowired; | 
| 25 | 28 | import org.springframework.context.annotation.Configuration; | 
| 26 | 29 | import org.springframework.context.annotation.ImportAware; | 
| 27 | 30 | import org.springframework.core.annotation.AnnotationAttributes; | 
| 28 | 31 | import org.springframework.core.type.AnnotationMetadata; | 
| 29 | 32 | import org.springframework.lang.Nullable; | 
| 30 | 33 | import org.springframework.util.CollectionUtils; | 
|  | 34 | +import org.springframework.util.function.SingletonSupplier; | 
| 31 | 35 | 
 | 
| 32 | 36 | /** | 
| 33 | 37 |  * Abstract base {@code Configuration} class providing common structure for enabling | 
| @@ -65,17 +69,27 @@ public void setImportMetadata(AnnotationMetadata importMetadata) { | 
| 65 | 69 | 	/** | 
| 66 | 70 | 	 * Collect any {@link AsyncConfigurer} beans through autowiring. | 
| 67 | 71 | 	 */ | 
| 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 | +		}; | 
| 79 | 93 | 	} | 
| 80 | 94 | 
 | 
| 81 | 95 | } | 
0 commit comments