18
18
19
19
import java .lang .annotation .Retention ;
20
20
import java .lang .annotation .RetentionPolicy ;
21
+ import java .util .HashMap ;
21
22
import java .util .concurrent .Future ;
22
23
23
- import org .junit .Before ;
24
+ import org .aopalliance .intercept .MethodInterceptor ;
25
+ import org .aopalliance .intercept .MethodInvocation ;
24
26
import org .junit .Test ;
25
27
28
+ import org .springframework .aop .framework .ProxyFactory ;
26
29
import org .springframework .aop .framework .autoproxy .DefaultAdvisorAutoProxyCreator ;
30
+ import org .springframework .aop .support .DefaultIntroductionAdvisor ;
31
+ import org .springframework .beans .factory .FactoryBean ;
27
32
import org .springframework .beans .factory .support .RootBeanDefinition ;
28
33
import org .springframework .context .ApplicationEvent ;
29
34
import org .springframework .context .ApplicationListener ;
30
35
import org .springframework .context .support .GenericApplicationContext ;
31
36
import org .springframework .scheduling .concurrent .ThreadPoolTaskExecutor ;
32
- import org .springframework .tests .Assume ;
33
- import org .springframework .tests .TestGroup ;
34
37
35
38
import static org .junit .Assert .*;
36
39
@@ -46,10 +49,6 @@ public class AsyncExecutionTests {
46
49
47
50
private static int listenerConstructed = 0 ;
48
51
49
- @ Before
50
- public void setUp () {
51
- Assume .group (TestGroup .PERFORMANCE );
52
- }
53
52
54
53
@ Test
55
54
public void asyncMethods () throws Exception {
@@ -135,6 +134,46 @@ public void asyncClass() throws Exception {
135
134
assertEquals ("20" , future .get ());
136
135
}
137
136
137
+ @ Test
138
+ public void asyncClassWithPostProcessor () throws Exception {
139
+ originalThreadName = Thread .currentThread ().getName ();
140
+ GenericApplicationContext context = new GenericApplicationContext ();
141
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (AsyncClassBean .class ));
142
+ context .registerBeanDefinition ("asyncProcessor" , new RootBeanDefinition (AsyncAnnotationBeanPostProcessor .class ));
143
+ context .refresh ();
144
+ AsyncClassBean asyncTest = context .getBean ("asyncTest" , AsyncClassBean .class );
145
+ asyncTest .doSomething (10 );
146
+ Future <String > future = asyncTest .returnSomething (20 );
147
+ assertEquals ("20" , future .get ());
148
+ }
149
+
150
+ @ Test
151
+ public void asyncClassWithInterface () throws Exception {
152
+ originalThreadName = Thread .currentThread ().getName ();
153
+ GenericApplicationContext context = new GenericApplicationContext ();
154
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (AsyncClassBeanWithInterface .class ));
155
+ context .registerBeanDefinition ("autoProxyCreator" , new RootBeanDefinition (DefaultAdvisorAutoProxyCreator .class ));
156
+ context .registerBeanDefinition ("asyncAdvisor" , new RootBeanDefinition (AsyncAnnotationAdvisor .class ));
157
+ context .refresh ();
158
+ RegularInterface asyncTest = context .getBean ("asyncTest" , RegularInterface .class );
159
+ asyncTest .doSomething (10 );
160
+ Future <String > future = asyncTest .returnSomething (20 );
161
+ assertEquals ("20" , future .get ());
162
+ }
163
+
164
+ @ Test
165
+ public void asyncClassWithInterfaceAndPostProcessor () throws Exception {
166
+ originalThreadName = Thread .currentThread ().getName ();
167
+ GenericApplicationContext context = new GenericApplicationContext ();
168
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (AsyncClassBeanWithInterface .class ));
169
+ context .registerBeanDefinition ("asyncProcessor" , new RootBeanDefinition (AsyncAnnotationBeanPostProcessor .class ));
170
+ context .refresh ();
171
+ RegularInterface asyncTest = context .getBean ("asyncTest" , RegularInterface .class );
172
+ asyncTest .doSomething (10 );
173
+ Future <String > future = asyncTest .returnSomething (20 );
174
+ assertEquals ("20" , future .get ());
175
+ }
176
+
138
177
@ Test
139
178
public void asyncInterface () throws Exception {
140
179
originalThreadName = Thread .currentThread ().getName ();
@@ -149,6 +188,46 @@ public void asyncInterface() throws Exception {
149
188
assertEquals ("20" , future .get ());
150
189
}
151
190
191
+ @ Test
192
+ public void asyncInterfaceWithPostProcessor () throws Exception {
193
+ originalThreadName = Thread .currentThread ().getName ();
194
+ GenericApplicationContext context = new GenericApplicationContext ();
195
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (AsyncInterfaceBean .class ));
196
+ context .registerBeanDefinition ("asyncProcessor" , new RootBeanDefinition (AsyncAnnotationBeanPostProcessor .class ));
197
+ context .refresh ();
198
+ AsyncInterface asyncTest = context .getBean ("asyncTest" , AsyncInterface .class );
199
+ asyncTest .doSomething (10 );
200
+ Future <String > future = asyncTest .returnSomething (20 );
201
+ assertEquals ("20" , future .get ());
202
+ }
203
+
204
+ @ Test
205
+ public void dynamicAsyncInterface () throws Exception {
206
+ originalThreadName = Thread .currentThread ().getName ();
207
+ GenericApplicationContext context = new GenericApplicationContext ();
208
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (DynamicAsyncInterfaceBean .class ));
209
+ context .registerBeanDefinition ("autoProxyCreator" , new RootBeanDefinition (DefaultAdvisorAutoProxyCreator .class ));
210
+ context .registerBeanDefinition ("asyncAdvisor" , new RootBeanDefinition (AsyncAnnotationAdvisor .class ));
211
+ context .refresh ();
212
+ AsyncInterface asyncTest = context .getBean ("asyncTest" , AsyncInterface .class );
213
+ asyncTest .doSomething (10 );
214
+ Future <String > future = asyncTest .returnSomething (20 );
215
+ assertEquals ("20" , future .get ());
216
+ }
217
+
218
+ @ Test
219
+ public void dynamicAsyncInterfaceWithPostProcessor () throws Exception {
220
+ originalThreadName = Thread .currentThread ().getName ();
221
+ GenericApplicationContext context = new GenericApplicationContext ();
222
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (DynamicAsyncInterfaceBean .class ));
223
+ context .registerBeanDefinition ("asyncProcessor" , new RootBeanDefinition (AsyncAnnotationBeanPostProcessor .class ));
224
+ context .refresh ();
225
+ AsyncInterface asyncTest = context .getBean ("asyncTest" , AsyncInterface .class );
226
+ asyncTest .doSomething (10 );
227
+ Future <String > future = asyncTest .returnSomething (20 );
228
+ assertEquals ("20" , future .get ());
229
+ }
230
+
152
231
@ Test
153
232
public void asyncMethodsInInterface () throws Exception {
154
233
originalThreadName = Thread .currentThread ().getName ();
@@ -164,6 +243,33 @@ public void asyncMethodsInInterface() throws Exception {
164
243
assertEquals ("20" , future .get ());
165
244
}
166
245
246
+ @ Test
247
+ public void asyncMethodsInInterfaceWithPostProcessor () throws Exception {
248
+ originalThreadName = Thread .currentThread ().getName ();
249
+ GenericApplicationContext context = new GenericApplicationContext ();
250
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (AsyncMethodsInterfaceBean .class ));
251
+ context .registerBeanDefinition ("asyncProcessor" , new RootBeanDefinition (AsyncAnnotationBeanPostProcessor .class ));
252
+ context .refresh ();
253
+ AsyncMethodsInterface asyncTest = context .getBean ("asyncTest" , AsyncMethodsInterface .class );
254
+ asyncTest .doNothing (5 );
255
+ asyncTest .doSomething (10 );
256
+ Future <String > future = asyncTest .returnSomething (20 );
257
+ assertEquals ("20" , future .get ());
258
+ }
259
+
260
+ @ Test
261
+ public void dynamicAsyncMethodsInInterfaceWithPostProcessor () throws Exception {
262
+ originalThreadName = Thread .currentThread ().getName ();
263
+ GenericApplicationContext context = new GenericApplicationContext ();
264
+ context .registerBeanDefinition ("asyncTest" , new RootBeanDefinition (DynamicAsyncMethodsInterfaceBean .class ));
265
+ context .registerBeanDefinition ("asyncProcessor" , new RootBeanDefinition (AsyncAnnotationBeanPostProcessor .class ));
266
+ context .refresh ();
267
+ AsyncMethodsInterface asyncTest = context .getBean ("asyncTest" , AsyncMethodsInterface .class );
268
+ asyncTest .doSomething (10 );
269
+ Future <String > future = asyncTest .returnSomething (20 );
270
+ assertEquals ("20" , future .get ());
271
+ }
272
+
167
273
@ Test
168
274
public void asyncMethodListener () throws Exception {
169
275
originalThreadName = Thread .currentThread ().getName ();
@@ -304,6 +410,28 @@ public Future<String> returnSomething(int i) {
304
410
}
305
411
306
412
413
+ public interface RegularInterface {
414
+
415
+ void doSomething (int i );
416
+
417
+ Future <String > returnSomething (int i );
418
+ }
419
+
420
+
421
+ @ Async
422
+ public static class AsyncClassBeanWithInterface implements RegularInterface {
423
+
424
+ public void doSomething (int i ) {
425
+ assertTrue (!Thread .currentThread ().getName ().equals (originalThreadName ));
426
+ }
427
+
428
+ public Future <String > returnSomething (int i ) {
429
+ assertTrue (!Thread .currentThread ().getName ().equals (originalThreadName ));
430
+ return new AsyncResult <String >(Integer .toString (i ));
431
+ }
432
+ }
433
+
434
+
307
435
@ Async
308
436
public interface AsyncInterface {
309
437
@@ -328,6 +456,44 @@ public Future<String> returnSomething(int i) {
328
456
}
329
457
330
458
459
+ public static class DynamicAsyncInterfaceBean implements FactoryBean <AsyncInterface > {
460
+
461
+ private final AsyncInterface proxy ;
462
+
463
+ public DynamicAsyncInterfaceBean () {
464
+ ProxyFactory pf = new ProxyFactory (new HashMap <>());
465
+ DefaultIntroductionAdvisor advisor = new DefaultIntroductionAdvisor (new MethodInterceptor () {
466
+ @ Override
467
+ public Object invoke (MethodInvocation invocation ) throws Throwable {
468
+ assertTrue (!Thread .currentThread ().getName ().equals (originalThreadName ));
469
+ if (Future .class .equals (invocation .getMethod ().getReturnType ())) {
470
+ return new AsyncResult <String >(invocation .getArguments ()[0 ].toString ());
471
+ }
472
+ return null ;
473
+ }
474
+ });
475
+ advisor .addInterface (AsyncInterface .class );
476
+ pf .addAdvisor (advisor );
477
+ this .proxy = (AsyncInterface ) pf .getProxy ();
478
+ }
479
+
480
+ @ Override
481
+ public AsyncInterface getObject () {
482
+ return this .proxy ;
483
+ }
484
+
485
+ @ Override
486
+ public Class <?> getObjectType () {
487
+ return this .proxy .getClass ();
488
+ }
489
+
490
+ @ Override
491
+ public boolean isSingleton () {
492
+ return true ;
493
+ }
494
+ }
495
+
496
+
331
497
public interface AsyncMethodsInterface {
332
498
333
499
void doNothing (int i );
@@ -360,6 +526,44 @@ public Future<String> returnSomething(int i) {
360
526
}
361
527
362
528
529
+ public static class DynamicAsyncMethodsInterfaceBean implements FactoryBean <AsyncMethodsInterface > {
530
+
531
+ private final AsyncMethodsInterface proxy ;
532
+
533
+ public DynamicAsyncMethodsInterfaceBean () {
534
+ ProxyFactory pf = new ProxyFactory (new HashMap <>());
535
+ DefaultIntroductionAdvisor advisor = new DefaultIntroductionAdvisor (new MethodInterceptor () {
536
+ @ Override
537
+ public Object invoke (MethodInvocation invocation ) throws Throwable {
538
+ assertTrue (!Thread .currentThread ().getName ().equals (originalThreadName ));
539
+ if (Future .class .equals (invocation .getMethod ().getReturnType ())) {
540
+ return new AsyncResult <String >(invocation .getArguments ()[0 ].toString ());
541
+ }
542
+ return null ;
543
+ }
544
+ });
545
+ advisor .addInterface (AsyncMethodsInterface .class );
546
+ pf .addAdvisor (advisor );
547
+ this .proxy = (AsyncMethodsInterface ) pf .getProxy ();
548
+ }
549
+
550
+ @ Override
551
+ public AsyncMethodsInterface getObject () {
552
+ return this .proxy ;
553
+ }
554
+
555
+ @ Override
556
+ public Class <?> getObjectType () {
557
+ return this .proxy .getClass ();
558
+ }
559
+
560
+ @ Override
561
+ public boolean isSingleton () {
562
+ return true ;
563
+ }
564
+ }
565
+
566
+
363
567
public static class AsyncMethodListener implements ApplicationListener <ApplicationEvent > {
364
568
365
569
@ Override
0 commit comments