|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2019 the original author or authors. |
| 2 | + * Copyright 2002-2022 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.
|
|
21 | 21 | import java.lang.annotation.RetentionPolicy;
|
22 | 22 | import java.lang.annotation.Target;
|
23 | 23 | import java.lang.reflect.Method;
|
| 24 | +import java.util.Properties; |
24 | 25 | import java.util.concurrent.ExecutionException;
|
25 | 26 | import java.util.concurrent.Executor;
|
26 | 27 | import java.util.concurrent.Executors;
|
|
47 | 48 | import org.springframework.context.annotation.Configuration;
|
48 | 49 | import org.springframework.context.annotation.Import;
|
49 | 50 | import org.springframework.context.annotation.Lazy;
|
| 51 | +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; |
50 | 52 | import org.springframework.core.Ordered;
|
51 | 53 | import org.springframework.lang.Nullable;
|
52 | 54 | import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
@@ -130,6 +132,29 @@ public void withAsyncBeanWithExecutorQualifiedByName() throws ExecutionException
|
130 | 132 | ctx.close();
|
131 | 133 | }
|
132 | 134 |
|
| 135 | + @Test |
| 136 | + public void withAsyncBeanWithExecutorQualifiedByExpression() throws ExecutionException, InterruptedException { |
| 137 | + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); |
| 138 | + System.getProperties().put("myExecutor", "myExecutor1"); |
| 139 | + PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer(); |
| 140 | + placeholderConfigurer.setProperties(new Properties() {{ |
| 141 | + put("my.app.myExecutor", "myExecutor2"); |
| 142 | + }}); |
| 143 | + placeholderConfigurer.postProcessBeanFactory(context.getBeanFactory()); |
| 144 | + |
| 145 | + context.register(AsyncWithExecutorQualifiedByExpressionConfig.class); |
| 146 | + context.refresh(); |
| 147 | + |
| 148 | + AsyncBeanWithExecutorQualifiedByExpression asyncBean = context.getBean(AsyncBeanWithExecutorQualifiedByExpression.class); |
| 149 | + Future<Thread> workerThread1 = asyncBean.myWork1(); |
| 150 | + assertThat(workerThread1.get().getName()).doesNotStartWith("myExecutor2-").startsWith("myExecutor1-"); |
| 151 | + |
| 152 | + Future<Thread> workerThread2 = asyncBean.myWork2(); |
| 153 | + assertThat(workerThread2.get().getName()).startsWith("myExecutor2-"); |
| 154 | + |
| 155 | + context.close(); |
| 156 | + } |
| 157 | + |
133 | 158 | @Test
|
134 | 159 | public void asyncProcessorIsOrderedLowestPrecedenceByDefault() {
|
135 | 160 | AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
@@ -346,6 +371,19 @@ public Future<Thread> work3() {
|
346 | 371 | }
|
347 | 372 | }
|
348 | 373 |
|
| 374 | + static class AsyncBeanWithExecutorQualifiedByExpression { |
| 375 | + |
| 376 | + @Async("#{systemProperties.myExecutor}") |
| 377 | + public Future<Thread> myWork1() { |
| 378 | + return new AsyncResult<>(Thread.currentThread()); |
| 379 | + } |
| 380 | + |
| 381 | + @Async("${my.app.myExecutor}") |
| 382 | + public Future<Thread> myWork2() { |
| 383 | + return new AsyncResult<>(Thread.currentThread()); |
| 384 | + } |
| 385 | + } |
| 386 | + |
349 | 387 |
|
350 | 388 | static class AsyncBean {
|
351 | 389 |
|
@@ -475,6 +513,27 @@ public Executor otherExecutor() {
|
475 | 513 | }
|
476 | 514 | }
|
477 | 515 |
|
| 516 | + @Configuration |
| 517 | + @EnableAsync |
| 518 | + static class AsyncWithExecutorQualifiedByExpressionConfig { |
| 519 | + |
| 520 | + @Bean |
| 521 | + public AsyncBeanWithExecutorQualifiedByExpression asyncBean() { |
| 522 | + return new AsyncBeanWithExecutorQualifiedByExpression(); |
| 523 | + } |
| 524 | + |
| 525 | + @Bean |
| 526 | + public Executor myExecutor1() { |
| 527 | + return new ThreadPoolTaskExecutor(); |
| 528 | + } |
| 529 | + |
| 530 | + @Bean |
| 531 | + @Qualifier("myExecutor") |
| 532 | + public Executor myExecutor2() { |
| 533 | + return new ThreadPoolTaskExecutor(); |
| 534 | + } |
| 535 | + } |
| 536 | + |
478 | 537 |
|
479 | 538 | @Configuration
|
480 | 539 | @EnableAsync
|
|
0 commit comments