From de10bb69cb129a45bba41c90b8a2e18d8305b764 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Wed, 15 Dec 2021 10:53:09 +0100 Subject: [PATCH] Stop resolving AsyncConfigurer instances eagerly Closes gh-27808 --- .../AbstractAsyncConfiguration.java | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java index 60955d50077..2558ab5684c 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,14 @@ package org.springframework.scheduling.annotation; -import java.util.Collection; +import java.util.List; import java.util.concurrent.Executor; +import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportAware; @@ -28,6 +31,7 @@ import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; +import org.springframework.util.function.SingletonSupplier; /** * Abstract base {@code Configuration} class providing common structure for enabling @@ -65,17 +69,27 @@ public abstract class AbstractAsyncConfiguration implements ImportAware { /** * Collect any {@link AsyncConfigurer} beans through autowiring. */ - @Autowired(required = false) - void setConfigurers(Collection 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; + @Autowired + void setConfigurers(ObjectProvider configurers) { + Supplier asyncConfigurer = SingletonSupplier.of(() -> { + List candidates = configurers.stream().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(candidates)) { + return null; + } + if (candidates.size() > 1) { + throw new IllegalStateException("Only one AsyncConfigurer may exist"); + } + return candidates.get(0); + }); + this.executor = adapt(asyncConfigurer, AsyncConfigurer::getAsyncExecutor); + this.exceptionHandler = adapt(asyncConfigurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler); + } + + private Supplier adapt(Supplier supplier, Function provider) { + return () -> { + AsyncConfigurer asyncConfigurer = supplier.get(); + return (asyncConfigurer != null) ? provider.apply(asyncConfigurer) : null; + }; } }