Support abstract, bridge, & interface methods in AnnotatedElementUtils

This commit introduces support for finding annotations on abstract,
bridge, and interface methods in AnnotatedElementUtils.

 - Introduced dedicated findAnnotationAttributes() methods in
   AnnotatedElementUtils that provide first-class support for
   processing methods, class hierarchies, interfaces, bridge methods,
   etc.

 - Introduced find/get search algorithm dichotomy in
   AnnotatedElementUtils which is visible in the public API as well as
   in the internal implementation. This was necessary in order to
   maintain backwards compatibility with the existing API (even though
   it was undocumented).

 - Reverted all recent changes made to the "get semantics" search
   algorithm in AnnotatedElementUtils in order to ensure backwards
   compatibility, and reverted recent changes to
   JtaTransactionAnnotationParser and SpringTransactionAnnotationParser
   accordingly.

 - Documented internal AnnotatedElementUtils.Processor<T> interface.

 - Enabled failing tests and introduced
   findAnnotationAttributesFromBridgeMethod() test in
   AnnotatedElementUtilsTests.

 - Refactored ApplicationListenerMethodAdapter.getCondition() and
   enabled failing test in TransactionalEventListenerTests.

 - AnnotationUtils.isInterfaceWithAnnotatedMethods() is now package
   private.

Issue: SPR-12738, SPR-11514, SPR-11598
This commit is contained in:
Sam Brannen
2015-04-24 00:55:48 +02:00
parent ececf32c05
commit ad6bea1cda
8 changed files with 506 additions and 199 deletions

View File

@@ -27,7 +27,6 @@ import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -150,16 +149,13 @@ public class TransactionalEventListenerTests {
getEventCollector().assertTotalEventsCount(1); // After rollback not invoked
}
// TODO [SPR-12738] Enable test.
@Ignore("Disabled until SPR-12738 is resolved")
@Test
public void afterCommitWithTransactionalComponentListenerProxiedViaDynamicProxy() {
load(TransactionalConfiguration.class, TransactionalComponentAfterCommitTestListener.class);
load(TransactionalConfiguration.class, TransactionalComponentTestListener.class);
this.transactionTemplate.execute(status -> {
getContext().publishEvent("SKIP");
getEventCollector().assertNoEventReceived();
return null;
});
getEventCollector().assertNoEventReceived();
}
@@ -280,7 +276,6 @@ public class TransactionalEventListenerTests {
getContext().publishEvent("SKIP");
getEventCollector().assertNoEventReceived();
return null;
});
getEventCollector().assertNoEventReceived();
}
@@ -460,14 +455,15 @@ public class TransactionalEventListenerTests {
@Transactional
@Component
static interface TransactionalComponentAfterCommitTestListenerInterface {
static interface TransactionalComponentTestListenerInterface {
@TransactionalEventListener(phase = AFTER_COMMIT, condition = "!'SKIP'.equals(#data)")
// Cannot use #data in condition due to dynamic proxy.
@TransactionalEventListener(condition = "!'SKIP'.equals(#p0)")
void handleAfterCommit(String data);
}
static class TransactionalComponentAfterCommitTestListener extends BaseTransactionalTestListener implements
TransactionalComponentAfterCommitTestListenerInterface {
static class TransactionalComponentTestListener extends BaseTransactionalTestListener implements
TransactionalComponentTestListenerInterface {
@Override
public void handleAfterCommit(String data) {