Simplify hint registration for Spring AOP proxies

Prior to this commit, when users wished to register proxy hints for a
Spring AOP JDK dynamic proxy, they were required to explicitly specify
SpringProxy, Advised, and DecoratingProxy along with user interfaces.

This commit simplifies hint registration for Spring AOP proxies by
introducing two completeJdkProxyInterfaces() methods in AopProxyUtils,
one that accepts strings and one that accepts classes that represent
the user-specified interfaces implemented the user component to be
proxied. The SpringProxy, Advised, and DecoratingProxy interfaces are
appended to the user-specified interfaces and returned as the complete
set of interfaces that the proxy will implement.

Closes gh-28745
This commit is contained in:
Sam Brannen
2022-07-10 20:09:49 +02:00
parent 2a0b3c1af9
commit 5178e9c28e
5 changed files with 141 additions and 13 deletions

View File

@@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.aop.SpringProxy;
import org.springframework.beans.testfixture.beans.ITestBean;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.core.DecoratingProxy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -108,4 +109,56 @@ class AopProxyUtilsTests {
assertThatIllegalArgumentException().isThrownBy(() -> AopProxyUtils.proxiedUserInterfaces(proxy));
}
@Test
void completeJdkProxyInterfacesFromClassThatIsNotAnInterface() {
assertThatIllegalArgumentException()
.isThrownBy(() -> AopProxyUtils.completeJdkProxyInterfaces(TestBean.class))
.withMessage(TestBean.class.getName() + " must be an interface");
}
@Test
void completeJdkProxyInterfacesFromSingleClass() {
Class<?>[] jdkProxyInterfaces = AopProxyUtils.completeJdkProxyInterfaces(ITestBean.class);
assertThat(jdkProxyInterfaces).containsExactly(
ITestBean.class, SpringProxy.class, Advised.class, DecoratingProxy.class);
}
@Test
void completeJdkProxyInterfacesFromMultipleClasses() {
Class<?>[] jdkProxyInterfaces = AopProxyUtils.completeJdkProxyInterfaces(ITestBean.class, Comparable.class);
assertThat(jdkProxyInterfaces).containsExactly(
ITestBean.class, Comparable.class, SpringProxy.class, Advised.class, DecoratingProxy.class);
}
@Test
void completeJdkProxyInterfacesIgnoresSealedInterfaces() {
Class<?>[] jdkProxyInterfaces = AopProxyUtils.completeJdkProxyInterfaces(SealedInterface.class, Comparable.class);
assertThat(jdkProxyInterfaces).containsExactly(
Comparable.class, SpringProxy.class, Advised.class, DecoratingProxy.class);
}
@Test
void completeJdkProxyInterfacesFromSingleClassName() {
String[] jdkProxyInterfaces = AopProxyUtils.completeJdkProxyInterfaces(ITestBean.class.getName());
assertThat(jdkProxyInterfaces).containsExactly(
ITestBean.class.getName(), SpringProxy.class.getName(), Advised.class.getName(),
DecoratingProxy.class.getName());
}
@Test
void completeJdkProxyInterfacesFromMultipleClassNames() {
String[] jdkProxyInterfaces =
AopProxyUtils.completeJdkProxyInterfaces(ITestBean.class.getName(), Comparable.class.getName());
assertThat(jdkProxyInterfaces).containsExactly(
ITestBean.class.getName(), Comparable.class.getName(), SpringProxy.class.getName(),
Advised.class.getName(), DecoratingProxy.class.getName());
}
sealed interface SealedInterface {
}
static final class SealedType implements SealedInterface {
}
}