ApplicationListenerMethodAdapter resolves order on construction
Issue: SPR-14642
This commit is contained in:
parent
391752abc2
commit
58fa63fdd1
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.context.event;
|
package org.springframework.context.event;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
|
|
@ -53,6 +52,7 @@ import org.springframework.util.StringUtils;
|
||||||
* evaluated prior to invoking the underlying method.
|
* evaluated prior to invoking the underlying method.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
|
|
@ -70,27 +70,59 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||||
|
|
||||||
private final List<ResolvableType> declaredEventTypes;
|
private final List<ResolvableType> declaredEventTypes;
|
||||||
|
|
||||||
|
private final String condition;
|
||||||
|
|
||||||
|
private final int order;
|
||||||
|
|
||||||
private final AnnotatedElementKey methodKey;
|
private final AnnotatedElementKey methodKey;
|
||||||
|
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
private EventExpressionEvaluator evaluator;
|
private EventExpressionEvaluator evaluator;
|
||||||
|
|
||||||
private String condition;
|
|
||||||
|
|
||||||
private EventListener eventListener;
|
|
||||||
|
|
||||||
|
|
||||||
public ApplicationListenerMethodAdapter(String beanName, Class<?> targetClass, Method method) {
|
public ApplicationListenerMethodAdapter(String beanName, Class<?> targetClass, Method method) {
|
||||||
this.beanName = beanName;
|
this.beanName = beanName;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.targetClass = targetClass;
|
this.targetClass = targetClass;
|
||||||
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
|
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<ResolvableType> 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<ResolvableType> 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.
|
* Initialize this instance.
|
||||||
*/
|
*/
|
||||||
|
|
@ -128,8 +160,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
Order order = getMethodAnnotation(Order.class);
|
return this.order;
|
||||||
return (order != null ? order.value() : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -164,8 +195,8 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||||
if (this.method.getParameterCount() == 0) {
|
if (this.method.getParameterCount() == 0) {
|
||||||
return new Object[0];
|
return new Object[0];
|
||||||
}
|
}
|
||||||
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass())
|
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) &&
|
||||||
&& event instanceof PayloadApplicationEvent) {
|
event instanceof PayloadApplicationEvent) {
|
||||||
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
|
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -212,10 +243,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
|
|
||||||
return AnnotatedElementUtils.findMergedAnnotation(this.method, annotationType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the event listener method with the given argument values.
|
* 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);
|
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.
|
* Return the condition to use.
|
||||||
* <p>Matches the {@code condition} attribute of the {@link EventListener}
|
* <p>Matches the {@code condition} attribute of the {@link EventListener}
|
||||||
|
|
@ -267,12 +287,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||||
* is meta-annotated with {@code @EventListener}.
|
* is meta-annotated with {@code @EventListener}.
|
||||||
*/
|
*/
|
||||||
protected String getCondition() {
|
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;
|
return this.condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -346,29 +360,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ResolvableType> 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<ResolvableType> 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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@ package org.springframework.transaction.event;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
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.ApplicationEvent;
|
||||||
import org.springframework.context.event.ApplicationListenerMethodAdapter;
|
import org.springframework.context.event.ApplicationListenerMethodAdapter;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
|
|
@ -41,14 +38,13 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||||
* bean of type {@link TransactionalEventListenerFactory} is required.
|
* bean of type {@link TransactionalEventListenerFactory} is required.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
* @see ApplicationListenerMethodAdapter
|
* @see ApplicationListenerMethodAdapter
|
||||||
* @see TransactionalEventListener
|
* @see TransactionalEventListener
|
||||||
*/
|
*/
|
||||||
class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerMethodAdapter {
|
class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerMethodAdapter {
|
||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
private final TransactionalEventListener annotation;
|
private final TransactionalEventListener annotation;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -56,7 +52,7 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
|
||||||
super(beanName, targetClass, method);
|
super(beanName, targetClass, method);
|
||||||
this.annotation = AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
|
this.annotation = AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
|
||||||
if (this.annotation == null) {
|
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);
|
TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
|
||||||
}
|
}
|
||||||
else if (this.annotation.fallbackExecution()) {
|
else if (this.annotation.fallbackExecution()) {
|
||||||
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK) {
|
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) {
|
||||||
logger.warn("Processing '" + event + "' as a fallback execution on AFTER_ROLLBACK phase.");
|
logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");
|
||||||
}
|
}
|
||||||
processEvent(event);
|
processEvent(event);
|
||||||
}
|
}
|
||||||
else {
|
else if (logger.isDebugEnabled()) {
|
||||||
if (logger.isDebugEnabled()) {
|
logger.debug("No transaction is running - skipping " + event);
|
||||||
logger.debug("No transaction is running, skipping '" + event + "' for '" + this + "'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,7 +79,6 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class TransactionSynchronizationEventAdapter extends TransactionSynchronizationAdapter {
|
private static class TransactionSynchronizationEventAdapter extends TransactionSynchronizationAdapter {
|
||||||
|
|
||||||
private final ApplicationListenerMethodAdapter listener;
|
private final ApplicationListenerMethodAdapter listener;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue