Skip to content

Commit 3b91dec

Browse files
committed
ApplicationListenerMethodAdapter resolves order on construction
Issue: SPR-14642 (cherry picked from commit 58fa63f)
1 parent 05f74b4 commit 3b91dec

File tree

2 files changed

+48
-64
lines changed

2 files changed

+48
-64
lines changed

spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.context.event;
1818

19-
import java.lang.annotation.Annotation;
2019
import java.lang.reflect.InvocationTargetException;
2120
import java.lang.reflect.Method;
2221
import java.lang.reflect.UndeclaredThrowableException;
@@ -53,6 +52,7 @@
5352
* evaluated prior to invoking the underlying method.
5453
*
5554
* @author Stephane Nicoll
55+
* @author Juergen Hoeller
5656
* @author Sam Brannen
5757
* @since 4.2
5858
*/
@@ -70,26 +70,58 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
7070

7171
private final List<ResolvableType> declaredEventTypes;
7272

73+
private final String condition;
74+
75+
private final int order;
76+
7377
private final AnnotatedElementKey methodKey;
7478

7579
private ApplicationContext applicationContext;
7680

7781
private EventExpressionEvaluator evaluator;
7882

79-
private String condition;
80-
81-
private EventListener eventListener;
82-
8383

8484
public ApplicationListenerMethodAdapter(String beanName, Class<?> targetClass, Method method) {
8585
this.beanName = beanName;
8686
this.method = method;
8787
this.targetClass = targetClass;
8888
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
89-
this.declaredEventTypes = resolveDeclaredEventTypes();
90-
this.methodKey = new AnnotatedElementKey(this.method, this.targetClass);
89+
90+
EventListener ann = AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
91+
this.declaredEventTypes = resolveDeclaredEventTypes(method, ann);
92+
this.condition = (ann != null ? ann.condition() : null);
93+
this.order = resolveOrder(method);
94+
95+
this.methodKey = new AnnotatedElementKey(method, targetClass);
96+
}
97+
98+
99+
private List<ResolvableType> resolveDeclaredEventTypes(Method method, EventListener ann) {
100+
int count = method.getParameterTypes().length;
101+
if (count > 1) {
102+
throw new IllegalStateException(
103+
"Maximum one parameter is allowed for event listener method: " + method);
104+
}
105+
if (ann != null && ann.classes().length > 0) {
106+
List<ResolvableType> types = new ArrayList<ResolvableType>(ann.classes().length);
107+
for (Class<?> eventType : ann.classes()) {
108+
types.add(ResolvableType.forClass(eventType));
109+
}
110+
return types;
111+
}
112+
else {
113+
if (count == 0) {
114+
throw new IllegalStateException(
115+
"Event parameter is mandatory for event listener method: " + method);
116+
}
117+
return Collections.singletonList(ResolvableType.forMethodParameter(method, 0));
118+
}
91119
}
92120

121+
private int resolveOrder(Method method) {
122+
Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class);
123+
return (ann != null ? ann.value() : 0);
124+
}
93125

94126
/**
95127
* Initialize this instance.
@@ -128,8 +160,7 @@ public boolean supportsSourceType(Class<?> sourceType) {
128160

129161
@Override
130162
public int getOrder() {
131-
Order order = getMethodAnnotation(Order.class);
132-
return (order != null ? order.value() : 0);
163+
return this.order;
133164
}
134165

135166

@@ -164,8 +195,8 @@ protected Object[] resolveArguments(ApplicationEvent event) {
164195
if (this.method.getParameterTypes().length == 0) {
165196
return new Object[0];
166197
}
167-
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass())
168-
&& event instanceof PayloadApplicationEvent) {
198+
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) &&
199+
event instanceof PayloadApplicationEvent) {
169200
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
170201
}
171202
else {
@@ -212,10 +243,6 @@ private boolean shouldHandle(ApplicationEvent event, Object[] args) {
212243
return true;
213244
}
214245

215-
protected <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
216-
return AnnotatedElementUtils.findMergedAnnotation(this.method, annotationType);
217-
}
218-
219246
/**
220247
* Invoke the event listener method with the given argument values.
221248
*/
@@ -253,26 +280,13 @@ protected Object getTargetBean() {
253280
return this.applicationContext.getBean(this.beanName);
254281
}
255282

256-
protected EventListener getEventListener() {
257-
if (this.eventListener == null) {
258-
this.eventListener = AnnotatedElementUtils.findMergedAnnotation(this.method, EventListener.class);
259-
}
260-
return this.eventListener;
261-
}
262-
263283
/**
264284
* Return the condition to use.
265285
* <p>Matches the {@code condition} attribute of the {@link EventListener}
266286
* annotation or any matching attribute on a composed annotation that
267287
* is meta-annotated with {@code @EventListener}.
268288
*/
269289
protected String getCondition() {
270-
if (this.condition == null) {
271-
EventListener eventListener = AnnotatedElementUtils.findMergedAnnotation(this.method, EventListener.class);
272-
if (eventListener != null) {
273-
this.condition = eventListener.condition();
274-
}
275-
}
276290
return this.condition;
277291
}
278292

@@ -346,29 +360,6 @@ private ResolvableType getResolvableType(ApplicationEvent event) {
346360
return null;
347361
}
348362

349-
private List<ResolvableType> resolveDeclaredEventTypes() {
350-
int count = this.method.getParameterTypes().length;
351-
if (count > 1) {
352-
throw new IllegalStateException(
353-
"Maximum one parameter is allowed for event listener method: " + this.method);
354-
}
355-
EventListener ann = getEventListener();
356-
if (ann != null && ann.classes().length > 0) {
357-
List<ResolvableType> types = new ArrayList<ResolvableType>();
358-
for (Class<?> eventType : ann.classes()) {
359-
types.add(ResolvableType.forClass(eventType));
360-
}
361-
return types;
362-
}
363-
else {
364-
if (count == 0) {
365-
throw new IllegalStateException(
366-
"Event parameter is mandatory for event listener method: " + this.method);
367-
}
368-
return Collections.singletonList(ResolvableType.forMethodParameter(this.method, 0));
369-
}
370-
}
371-
372363

373364
@Override
374365
public String toString() {

spring-tx/src/main/java/org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818

1919
import java.lang.reflect.Method;
2020

21-
import org.apache.commons.logging.Log;
22-
import org.apache.commons.logging.LogFactory;
23-
2421
import org.springframework.context.ApplicationEvent;
2522
import org.springframework.context.event.ApplicationListenerMethodAdapter;
2623
import org.springframework.context.event.EventListener;
@@ -41,22 +38,21 @@
4138
* bean of type {@link TransactionalEventListenerFactory} is required.
4239
*
4340
* @author Stephane Nicoll
41+
* @author Juergen Hoeller
4442
* @since 4.2
4543
* @see ApplicationListenerMethodAdapter
4644
* @see TransactionalEventListener
4745
*/
4846
class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerMethodAdapter {
4947

50-
protected final Log logger = LogFactory.getLog(getClass());
51-
5248
private final TransactionalEventListener annotation;
5349

5450

5551
public ApplicationListenerMethodTransactionalAdapter(String beanName, Class<?> targetClass, Method method) {
5652
super(beanName, targetClass, method);
5753
this.annotation = AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
5854
if (this.annotation == null) {
59-
throw new IllegalStateException("No TransactionalEventListener annotation found on '" + method + "'");
55+
throw new IllegalStateException("No TransactionalEventListener annotation found on method: " + method);
6056
}
6157
}
6258

@@ -68,15 +64,13 @@ public void onApplicationEvent(ApplicationEvent event) {
6864
TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
6965
}
7066
else if (this.annotation.fallbackExecution()) {
71-
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK) {
72-
logger.warn("Processing '" + event + "' as a fallback execution on AFTER_ROLLBACK phase.");
67+
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) {
68+
logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");
7369
}
7470
processEvent(event);
7571
}
76-
else {
77-
if (logger.isDebugEnabled()) {
78-
logger.debug("No transaction is running, skipping '" + event + "' for '" + this + "'");
79-
}
72+
else if (logger.isDebugEnabled()) {
73+
logger.debug("No transaction is running - skipping " + event);
8074
}
8175
}
8276

@@ -85,7 +79,6 @@ private TransactionSynchronization createTransactionSynchronization(ApplicationE
8579
}
8680

8781

88-
8982
private static class TransactionSynchronizationEventAdapter extends TransactionSynchronizationAdapter {
9083

9184
private final ApplicationListenerMethodAdapter listener;

0 commit comments

Comments
 (0)