Optimize SpEL and property placeholder support for @Async qualifiers

See gh-27818
Closes gh-28549
This commit is contained in:
hebo
2022-06-01 07:46:09 +08:00
committed by Sam Brannen
parent 64412907f7
commit 2434470457
2 changed files with 18 additions and 4 deletions

View File

@@ -41,6 +41,7 @@ import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
import org.springframework.util.function.SingletonSupplier;
/**
@@ -56,6 +57,7 @@ import org.springframework.util.function.SingletonSupplier;
* @author Chris Beams
* @author Juergen Hoeller
* @author Stephane Nicoll
* @author He Bo
* @since 3.1.2
*/
public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
@@ -80,6 +82,8 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
@Nullable
private BeanFactory beanFactory;
@Nullable
private StringValueResolver stringValueResolver;
/**
* Create a new instance with a default {@link AsyncUncaughtExceptionHandler}.
@@ -150,6 +154,9 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
if (beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory) {
this.stringValueResolver = new EmbeddedValueResolver(configurableBeanFactory);
}
}
@@ -163,6 +170,9 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
if (executor == null) {
Executor targetExecutor;
String qualifier = getExecutorQualifier(method);
if (this.stringValueResolver != null && StringUtils.hasLength(qualifier)) {
qualifier = this.stringValueResolver.resolveStringValue(qualifier);
}
if (StringUtils.hasLength(qualifier)) {
targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
}
@@ -206,10 +216,6 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
" to access qualified executor '" + qualifier + "'");
}
if (beanFactory instanceof ConfigurableBeanFactory configurableBeanFactory) {
EmbeddedValueResolver embeddedValueResolver = new EmbeddedValueResolver(configurableBeanFactory);
qualifier = embeddedValueResolver.resolveStringValue(qualifier);
}
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier);
}

View File

@@ -146,6 +146,9 @@ public class EnableAsyncTests {
Future<Thread> workerThread2 = asyncBean.myWork2();
assertThat(workerThread2.get().getName()).startsWith("myExecutor2-");
Future<Thread> workerThread3 = asyncBean.defaultExecutor();
assertThat(workerThread3.get().getName()).startsWith("SimpleAsyncTaskExecutor");
}
finally {
System.clearProperty("myExecutor");
@@ -382,6 +385,11 @@ public class EnableAsyncTests {
public Future<Thread> myWork2() {
return new AsyncResult<>(Thread.currentThread());
}
@Async("${my.app.targetExecutor:}")
public Future<Thread> defaultExecutor() {
return new AsyncResult<>(Thread.currentThread());
}
}