AopUtils.getMostSpecificMethod exposes dynamic proxy class methods

Includes efficient canApply check for IntroductionAwareMethodMatcher.

Issue: SPR-16757
This commit is contained in:
Juergen Hoeller
2018-04-27 18:23:34 +02:00
parent 75a41db071
commit aa11721ff0
5 changed files with 100 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -167,10 +167,13 @@ public class AnnotationTransactionInterceptorTests {
proxy.doSomething();
assertGetTransactionAndCommitCount(4);
proxy.doSomethingDefault();
assertGetTransactionAndCommitCount(5);
}
@Test
public void crossClassInterfaceMethodLevelOnJdkProxy() throws Exception {
public void crossClassInterfaceMethodLevelOnJdkProxy() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new SomeServiceImpl());
proxyFactory.addInterface(SomeService.class);
@@ -189,7 +192,7 @@ public class AnnotationTransactionInterceptorTests {
}
@Test
public void crossClassInterfaceOnJdkProxy() throws Exception {
public void crossClassInterfaceOnJdkProxy() {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new OtherServiceImpl());
proxyFactory.addInterface(OtherService.class);
@@ -201,6 +204,64 @@ public class AnnotationTransactionInterceptorTests {
assertGetTransactionAndCommitCount(1);
}
@Test
public void withInterfaceOnTargetJdkProxy() {
ProxyFactory targetFactory = new ProxyFactory();
targetFactory.setTarget(new TestWithInterfaceImpl());
targetFactory.addInterface(TestWithInterface.class);
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(targetFactory.getProxy());
proxyFactory.addInterface(TestWithInterface.class);
proxyFactory.addAdvice(this.ti);
TestWithInterface proxy = (TestWithInterface) proxyFactory.getProxy();
proxy.doSomething();
assertGetTransactionAndCommitCount(1);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(2);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(3);
proxy.doSomething();
assertGetTransactionAndCommitCount(4);
proxy.doSomethingDefault();
assertGetTransactionAndCommitCount(5);
}
@Test
public void withInterfaceOnTargetCglibProxy() {
ProxyFactory targetFactory = new ProxyFactory();
targetFactory.setTarget(new TestWithInterfaceImpl());
targetFactory.setProxyTargetClass(true);
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(targetFactory.getProxy());
proxyFactory.addInterface(TestWithInterface.class);
proxyFactory.addAdvice(this.ti);
TestWithInterface proxy = (TestWithInterface) proxyFactory.getProxy();
proxy.doSomething();
assertGetTransactionAndCommitCount(1);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(2);
proxy.doSomethingElse();
assertGetTransactionAndCommitCount(3);
proxy.doSomething();
assertGetTransactionAndCommitCount(4);
proxy.doSomethingDefault();
assertGetTransactionAndCommitCount(5);
}
private void assertGetTransactionAndCommitCount(int expectedCount) {
assertEquals(expectedCount, this.ptm.begun);
assertEquals(expectedCount, this.ptm.commits);
@@ -309,13 +370,22 @@ public class AnnotationTransactionInterceptorTests {
}
@Transactional
public static interface TestWithInterface {
public interface BaseInterface {
public void doSomething();
void doSomething();
}
@Transactional
public interface TestWithInterface extends BaseInterface {
@Transactional(readOnly = true)
public void doSomethingElse();
void doSomethingElse();
default void doSomethingDefault() {
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
}
}
@@ -335,7 +405,7 @@ public class AnnotationTransactionInterceptorTests {
}
public static interface SomeService {
public interface SomeService {
void foo();