From 58fa63fdd109af831d8c674f640029b43a03b5ed Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 30 Aug 2016 20:50:02 +0200 Subject: [PATCH] ApplicationListenerMethodAdapter resolves order on construction Issue: SPR-14642 --- .../ApplicationListenerMethodAdapter.java | 93 +++++++++---------- ...ionListenerMethodTransactionalAdapter.java | 19 ++-- 2 files changed, 48 insertions(+), 64 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index 4153b063b35..deb172523aa 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -16,7 +16,6 @@ package org.springframework.context.event; -import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.UndeclaredThrowableException; @@ -53,6 +52,7 @@ import org.springframework.util.StringUtils; * evaluated prior to invoking the underlying method. * * @author Stephane Nicoll + * @author Juergen Hoeller * @author Sam Brannen * @since 4.2 */ @@ -70,26 +70,58 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe private final List declaredEventTypes; + private final String condition; + + private final int order; + private final AnnotatedElementKey methodKey; private ApplicationContext applicationContext; private EventExpressionEvaluator evaluator; - private String condition; - - private EventListener eventListener; - public ApplicationListenerMethodAdapter(String beanName, Class targetClass, Method method) { this.beanName = beanName; this.method = method; this.targetClass = targetClass; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); - this.declaredEventTypes = resolveDeclaredEventTypes(); - this.methodKey = new AnnotatedElementKey(this.method, this.targetClass); + + EventListener ann = AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class); + this.declaredEventTypes = resolveDeclaredEventTypes(method, ann); + this.condition = (ann != null ? ann.condition() : null); + this.order = resolveOrder(method); + + this.methodKey = new AnnotatedElementKey(method, targetClass); + } + + + private List resolveDeclaredEventTypes(Method method, EventListener ann) { + int count = method.getParameterCount(); + if (count > 1) { + throw new IllegalStateException( + "Maximum one parameter is allowed for event listener method: " + method); + } + if (ann != null && ann.classes().length > 0) { + List types = new ArrayList<>(ann.classes().length); + for (Class eventType : ann.classes()) { + types.add(ResolvableType.forClass(eventType)); + } + return types; + } + else { + if (count == 0) { + throw new IllegalStateException( + "Event parameter is mandatory for event listener method: " + method); + } + return Collections.singletonList(ResolvableType.forMethodParameter(method, 0)); + } } + private int resolveOrder(Method method) { + Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class); + return (ann != null ? ann.value() : 0); + } /** * Initialize this instance. @@ -128,8 +160,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe @Override public int getOrder() { - Order order = getMethodAnnotation(Order.class); - return (order != null ? order.value() : 0); + return this.order; } @@ -164,8 +195,8 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe if (this.method.getParameterCount() == 0) { return new Object[0]; } - if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) - && event instanceof PayloadApplicationEvent) { + if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) && + event instanceof PayloadApplicationEvent) { return new Object[] {((PayloadApplicationEvent) event).getPayload()}; } else { @@ -212,10 +243,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe return true; } - protected A getMethodAnnotation(Class annotationType) { - return AnnotatedElementUtils.findMergedAnnotation(this.method, annotationType); - } - /** * Invoke the event listener method with the given argument values. */ @@ -253,13 +280,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe return this.applicationContext.getBean(this.beanName); } - protected EventListener getEventListener() { - if (this.eventListener == null) { - this.eventListener = AnnotatedElementUtils.findMergedAnnotation(this.method, EventListener.class); - } - return this.eventListener; - } - /** * Return the condition to use. *

Matches the {@code condition} attribute of the {@link EventListener} @@ -267,12 +287,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe * is meta-annotated with {@code @EventListener}. */ protected String getCondition() { - if (this.condition == null) { - EventListener eventListener = AnnotatedElementUtils.findMergedAnnotation(this.method, EventListener.class); - if (eventListener != null) { - this.condition = eventListener.condition(); - } - } return this.condition; } @@ -346,29 +360,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe return null; } - private List resolveDeclaredEventTypes() { - int count = this.method.getParameterCount(); - if (count > 1) { - throw new IllegalStateException( - "Maximum one parameter is allowed for event listener method: " + this.method); - } - EventListener ann = getEventListener(); - if (ann != null && ann.classes().length > 0) { - List types = new ArrayList<>(); - for (Class eventType : ann.classes()) { - types.add(ResolvableType.forClass(eventType)); - } - return types; - } - else { - if (count == 0) { - throw new IllegalStateException( - "Event parameter is mandatory for event listener method: " + this.method); - } - return Collections.singletonList(ResolvableType.forMethodParameter(this.method, 0)); - } - } - @Override public String toString() { diff --git a/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java index 23db045521f..5998522c692 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java +++ b/spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java @@ -18,9 +18,6 @@ package org.springframework.transaction.event; import java.lang.reflect.Method; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import org.springframework.context.ApplicationEvent; import org.springframework.context.event.ApplicationListenerMethodAdapter; import org.springframework.context.event.EventListener; @@ -41,14 +38,13 @@ import org.springframework.transaction.support.TransactionSynchronizationManager * bean of type {@link TransactionalEventListenerFactory} is required. * * @author Stephane Nicoll + * @author Juergen Hoeller * @since 4.2 * @see ApplicationListenerMethodAdapter * @see TransactionalEventListener */ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerMethodAdapter { - protected final Log logger = LogFactory.getLog(getClass()); - private final TransactionalEventListener annotation; @@ -56,7 +52,7 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM super(beanName, targetClass, method); this.annotation = AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class); if (this.annotation == null) { - throw new IllegalStateException("No TransactionalEventListener annotation found on '" + method + "'"); + throw new IllegalStateException("No TransactionalEventListener annotation found on method: " + method); } } @@ -68,15 +64,13 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM TransactionSynchronizationManager.registerSynchronization(transactionSynchronization); } else if (this.annotation.fallbackExecution()) { - if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK) { - logger.warn("Processing '" + event + "' as a fallback execution on AFTER_ROLLBACK phase."); + if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) { + logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase"); } processEvent(event); } - else { - if (logger.isDebugEnabled()) { - logger.debug("No transaction is running, skipping '" + event + "' for '" + this + "'"); - } + else if (logger.isDebugEnabled()) { + logger.debug("No transaction is running - skipping " + event); } } @@ -85,7 +79,6 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM } - private static class TransactionSynchronizationEventAdapter extends TransactionSynchronizationAdapter { private final ApplicationListenerMethodAdapter listener;