Skip to content

Commit 3c4d535

Browse files
committed
Merge branch '6.2.x'
2 parents 0db2c7d + a4d99d6 commit 3c4d535

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -124,7 +124,7 @@ public AsyncExecutionInterceptor(@Nullable Executor defaultExecutor, AsyncUncaug
124124
return null;
125125
};
126126

127-
return doSubmit(task, executor, invocation.getMethod().getReturnType());
127+
return doSubmit(task, executor, userMethod.getReturnType());
128128
}
129129

130130
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2002-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.aop.interceptor;
18+
19+
import java.util.concurrent.Callable;
20+
import java.util.concurrent.CompletableFuture;
21+
import java.util.concurrent.Future;
22+
23+
import org.aopalliance.intercept.MethodInvocation;
24+
import org.junit.jupiter.api.Test;
25+
import org.mockito.ArgumentCaptor;
26+
27+
import org.springframework.core.task.AsyncTaskExecutor;
28+
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.mockito.BDDMockito.given;
31+
import static org.mockito.Mockito.any;
32+
import static org.mockito.Mockito.mock;
33+
import static org.mockito.Mockito.spy;
34+
import static org.mockito.Mockito.verify;
35+
36+
37+
/**
38+
* Tests for {@link AsyncExecutionInterceptor}.
39+
*
40+
* @author Bao Ngo
41+
* @since 7.0
42+
*/
43+
class AsyncExecutionInterceptorTests {
44+
45+
@Test
46+
@SuppressWarnings("unchecked")
47+
void invokeOnInterfaceWithGeneric() throws Throwable {
48+
AsyncExecutionInterceptor interceptor = spy(new AsyncExecutionInterceptor(null));
49+
FutureRunner impl = new FutureRunner();
50+
MethodInvocation mi = mock();
51+
given(mi.getThis()).willReturn(impl);
52+
given(mi.getMethod()).willReturn(GenericRunner.class.getMethod("run"));
53+
54+
interceptor.invoke(mi);
55+
ArgumentCaptor<Class<?>> classArgumentCaptor = ArgumentCaptor.forClass(Class.class);
56+
verify(interceptor).doSubmit(any(Callable.class), any(AsyncTaskExecutor.class), classArgumentCaptor.capture());
57+
assertThat(classArgumentCaptor.getValue()).isEqualTo(Future.class);
58+
}
59+
60+
61+
interface GenericRunner<O> {
62+
63+
O run();
64+
}
65+
66+
static class FutureRunner implements GenericRunner<Future<Void>> {
67+
@Override
68+
public Future<Void> run() {
69+
return CompletableFuture.runAsync(() -> {
70+
});
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)