Refine allocation of DefaultMethodInvokingMethodInterceptor.

We now reduce allocations of DefaultMethodInvokingMethodInterceptor by reusing DefaultMethodInvokingMethodInterceptor within a ProxyProjectionFactory. We also reduced allocations during default method discovery and reuse the default methods information within the projection information cache.

Closes #2831
This commit is contained in:
Mark Paluch
2023-05-17 10:28:20 +02:00
parent e4f05deed8
commit 54ffee0ab8
3 changed files with 67 additions and 27 deletions

View File

@@ -28,7 +28,7 @@ import java.util.Map;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.framework.Advised;
import org.springframework.test.util.ReflectionTestUtils;
@@ -137,16 +137,31 @@ class ProxyProjectionFactoryUnitTests {
assertThat(result).hasSize(6);
}
@Test // DATACMNS-655
@Test // DATACMNS-655, GH-2831
void invokesDefaultMethodOnProxy() {
var excerpt = factory.createProjection(CustomerExcerptWithDefaultMethod.class);
var advised = (Advised) ReflectionTestUtils.getField(Proxy.getInvocationHandler(excerpt), "advised");
var advisors = advised.getAdvisors();
assertThat(advisors.length).isGreaterThan(0);
assertThat(advisors[0].getAdvice()).isInstanceOf(DefaultMethodInvokingMethodInterceptor.class);
}
@Test // GH-2831
void doesNotRegisterDefaultMethodInvokingMethodInterceptor() {
var excerpt = factory.createProjection(CustomerExcerpt.class);
var advised = (Advised) ReflectionTestUtils.getField(Proxy.getInvocationHandler(excerpt), "advised");
var advisors = advised.getAdvisors();
assertThat(advisors.length).isGreaterThan(0);
assertThat(advisors[0].getAdvice()).isInstanceOf(DefaultMethodInvokingMethodInterceptor.class);
for (Advisor advisor : advisors) {
assertThat(advisor).isNotInstanceOf(DefaultMethodInvokingMethodInterceptor.class);
}
}
@Test // DATACMNS-648
@@ -271,8 +286,7 @@ class ProxyProjectionFactoryUnitTests {
customer.address.city = "New York";
customer.address.zipCode = "ZIP";
var excerpt = factory.createProjection(CustomerWithOptionalHavingProjection.class,
customer);
var excerpt = factory.createProjection(CustomerWithOptionalHavingProjection.class, customer);
assertThat(excerpt.getFirstname()).isEqualTo("Dave");
assertThat(excerpt.getAddress()).hasValueSatisfying(addressExcerpt -> {
@@ -343,6 +357,13 @@ class ProxyProjectionFactoryUnitTests {
Map<String, Object> getData();
}
interface CustomerExcerptWithDefaultMethod extends CustomerExcerpt {
default String getFirstnameAndId() {
return getFirstname() + " " + getId();
}
}
interface AddressExcerpt {
String getZipCode();