|
|
|
@ -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,26 +70,58 @@ 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() { |
|
|
|
|