|
|
|
@ -18,6 +18,7 @@ package org.springframework.context.event; |
|
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.InvocationTargetException; |
|
|
|
import java.lang.reflect.InvocationTargetException; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
|
|
|
import java.lang.reflect.Proxy; |
|
|
|
import java.lang.reflect.UndeclaredThrowableException; |
|
|
|
import java.lang.reflect.UndeclaredThrowableException; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collection; |
|
|
|
@ -27,6 +28,7 @@ import java.util.List; |
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.aop.support.AopUtils; |
|
|
|
import org.springframework.context.ApplicationContext; |
|
|
|
import org.springframework.context.ApplicationContext; |
|
|
|
import org.springframework.context.ApplicationEvent; |
|
|
|
import org.springframework.context.ApplicationEvent; |
|
|
|
import org.springframework.context.PayloadApplicationEvent; |
|
|
|
import org.springframework.context.PayloadApplicationEvent; |
|
|
|
@ -35,10 +37,8 @@ import org.springframework.core.BridgeMethodResolver; |
|
|
|
import org.springframework.core.ResolvableType; |
|
|
|
import org.springframework.core.ResolvableType; |
|
|
|
import org.springframework.core.annotation.AnnotatedElementUtils; |
|
|
|
import org.springframework.core.annotation.AnnotatedElementUtils; |
|
|
|
import org.springframework.core.annotation.Order; |
|
|
|
import org.springframework.core.annotation.Order; |
|
|
|
import org.springframework.expression.EvaluationContext; |
|
|
|
|
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
import org.springframework.util.ObjectUtils; |
|
|
|
import org.springframework.util.ObjectUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
@ -66,9 +66,9 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe |
|
|
|
|
|
|
|
|
|
|
|
private final Method method; |
|
|
|
private final Method method; |
|
|
|
|
|
|
|
|
|
|
|
private final Class<?> targetClass; |
|
|
|
private final Method targetMethod; |
|
|
|
|
|
|
|
|
|
|
|
private final Method bridgedMethod; |
|
|
|
private final AnnotatedElementKey methodKey; |
|
|
|
|
|
|
|
|
|
|
|
private final List<ResolvableType> declaredEventTypes; |
|
|
|
private final List<ResolvableType> declaredEventTypes; |
|
|
|
|
|
|
|
|
|
|
|
@ -77,8 +77,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe |
|
|
|
|
|
|
|
|
|
|
|
private final int order; |
|
|
|
private final int order; |
|
|
|
|
|
|
|
|
|
|
|
private final AnnotatedElementKey methodKey; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private ApplicationContext applicationContext; |
|
|
|
private ApplicationContext applicationContext; |
|
|
|
|
|
|
|
|
|
|
|
@ -88,18 +86,15 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe |
|
|
|
|
|
|
|
|
|
|
|
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 = BridgeMethodResolver.findBridgedMethod(method); |
|
|
|
this.targetClass = targetClass; |
|
|
|
this.targetMethod = (!Proxy.isProxyClass(targetClass) ? |
|
|
|
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); |
|
|
|
AopUtils.getMostSpecificMethod(method, targetClass) : this.method); |
|
|
|
|
|
|
|
this.methodKey = new AnnotatedElementKey(this.targetMethod, targetClass); |
|
|
|
Method targetMethod = ClassUtils.getMostSpecificMethod(method, targetClass); |
|
|
|
|
|
|
|
EventListener ann = AnnotatedElementUtils.findMergedAnnotation(targetMethod, EventListener.class); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EventListener ann = AnnotatedElementUtils.findMergedAnnotation(this.targetMethod, EventListener.class); |
|
|
|
this.declaredEventTypes = resolveDeclaredEventTypes(method, ann); |
|
|
|
this.declaredEventTypes = resolveDeclaredEventTypes(method, ann); |
|
|
|
this.condition = (ann != null ? ann.condition() : null); |
|
|
|
this.condition = (ann != null ? ann.condition() : null); |
|
|
|
this.order = resolveOrder(method); |
|
|
|
this.order = resolveOrder(method); |
|
|
|
|
|
|
|
|
|
|
|
this.methodKey = new AnnotatedElementKey(method, targetClass); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -109,21 +104,24 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe |
|
|
|
throw new IllegalStateException( |
|
|
|
throw new IllegalStateException( |
|
|
|
"Maximum one parameter is allowed for event listener method: " + method); |
|
|
|
"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); |
|
|
|
if (ann != null) { |
|
|
|
for (Class<?> eventType : ann.classes()) { |
|
|
|
Class<?>[] classes = ann.classes(); |
|
|
|
|
|
|
|
if (classes.length > 0) { |
|
|
|
|
|
|
|
List<ResolvableType> types = new ArrayList<>(classes.length); |
|
|
|
|
|
|
|
for (Class<?> eventType : classes) { |
|
|
|
types.add(ResolvableType.forClass(eventType)); |
|
|
|
types.add(ResolvableType.forClass(eventType)); |
|
|
|
} |
|
|
|
} |
|
|
|
return types; |
|
|
|
return types; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (count == 0) { |
|
|
|
if (count == 0) { |
|
|
|
throw new IllegalStateException( |
|
|
|
throw new IllegalStateException( |
|
|
|
"Event parameter is mandatory for event listener method: " + method); |
|
|
|
"Event parameter is mandatory for event listener method: " + method); |
|
|
|
} |
|
|
|
} |
|
|
|
return Collections.singletonList(ResolvableType.forMethodParameter(method, 0)); |
|
|
|
return Collections.singletonList(ResolvableType.forMethodParameter(method, 0)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private int resolveOrder(Method method) { |
|
|
|
private int resolveOrder(Method method) { |
|
|
|
Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class); |
|
|
|
Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class); |
|
|
|
@ -245,10 +243,9 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe |
|
|
|
} |
|
|
|
} |
|
|
|
String condition = getCondition(); |
|
|
|
String condition = getCondition(); |
|
|
|
if (StringUtils.hasText(condition)) { |
|
|
|
if (StringUtils.hasText(condition)) { |
|
|
|
Assert.notNull(this.evaluator, "EventExpressionEvaluator must no be null"); |
|
|
|
Assert.notNull(this.evaluator, "EventExpressionEvaluator must not be null"); |
|
|
|
EvaluationContext evaluationContext = this.evaluator.createEvaluationContext( |
|
|
|
return this.evaluator.condition( |
|
|
|
event, this.targetClass, this.method, args, this.applicationContext); |
|
|
|
condition, event, this.targetMethod, this.methodKey, args, this.applicationContext); |
|
|
|
return this.evaluator.condition(condition, this.methodKey, evaluationContext); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -259,12 +256,12 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
protected Object doInvoke(Object... args) { |
|
|
|
protected Object doInvoke(Object... args) { |
|
|
|
Object bean = getTargetBean(); |
|
|
|
Object bean = getTargetBean(); |
|
|
|
ReflectionUtils.makeAccessible(this.bridgedMethod); |
|
|
|
ReflectionUtils.makeAccessible(this.method); |
|
|
|
try { |
|
|
|
try { |
|
|
|
return this.bridgedMethod.invoke(bean, args); |
|
|
|
return this.method.invoke(bean, args); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (IllegalArgumentException ex) { |
|
|
|
catch (IllegalArgumentException ex) { |
|
|
|
assertTargetBean(this.bridgedMethod, bean, args); |
|
|
|
assertTargetBean(this.method, bean, args); |
|
|
|
throw new IllegalStateException(getInvocationErrorMessage(bean, ex.getMessage(), args), ex); |
|
|
|
throw new IllegalStateException(getInvocationErrorMessage(bean, ex.getMessage(), args), ex); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (IllegalAccessException ex) { |
|
|
|
catch (IllegalAccessException ex) { |
|
|
|
@ -311,7 +308,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe |
|
|
|
StringBuilder sb = new StringBuilder(message).append("\n"); |
|
|
|
StringBuilder sb = new StringBuilder(message).append("\n"); |
|
|
|
sb.append("HandlerMethod details: \n"); |
|
|
|
sb.append("HandlerMethod details: \n"); |
|
|
|
sb.append("Bean [").append(bean.getClass().getName()).append("]\n"); |
|
|
|
sb.append("Bean [").append(bean.getClass().getName()).append("]\n"); |
|
|
|
sb.append("Method [").append(this.bridgedMethod.toGenericString()).append("]\n"); |
|
|
|
sb.append("Method [").append(this.method.toGenericString()).append("]\n"); |
|
|
|
return sb.toString(); |
|
|
|
return sb.toString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|