Merge branch '6.0.x'
This commit is contained in:
commit
841124af75
|
|
@ -237,33 +237,28 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
|||
|
||||
private AutowiredArguments resolveArguments(RegisteredBean registeredBean, Executable executable) {
|
||||
Assert.isInstanceOf(AbstractAutowireCapableBeanFactory.class, registeredBean.getBeanFactory());
|
||||
String beanName = registeredBean.getBeanName();
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
AbstractAutowireCapableBeanFactory beanFactory =
|
||||
(AbstractAutowireCapableBeanFactory) registeredBean.getBeanFactory();
|
||||
RootBeanDefinition mergedBeanDefinition = registeredBean.getMergedBeanDefinition();
|
||||
|
||||
int startIndex = (executable instanceof Constructor<?> constructor &&
|
||||
ClassUtils.isInnerClass(constructor.getDeclaringClass())) ? 1 : 0;
|
||||
int parameterCount = executable.getParameterCount();
|
||||
Object[] resolved = new Object[parameterCount - startIndex];
|
||||
Assert.isTrue(this.shortcuts == null || this.shortcuts.length == resolved.length,
|
||||
() -> "'shortcuts' must contain " + resolved.length + " elements");
|
||||
|
||||
ConstructorArgumentValues argumentValues = resolveArgumentValues(registeredBean);
|
||||
Set<String> autowiredBeans = new LinkedHashSet<>(resolved.length);
|
||||
ConstructorArgumentValues argumentValues = resolveArgumentValues(beanFactory,
|
||||
beanName, mergedBeanDefinition);
|
||||
for (int i = startIndex; i < parameterCount; i++) {
|
||||
MethodParameter parameter = getMethodParameter(executable, i);
|
||||
DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(parameter, true);
|
||||
String shortcut = (this.shortcuts != null) ? this.shortcuts[i - startIndex] : null;
|
||||
DependencyDescriptor descriptor = new DependencyDescriptor(parameter, true);
|
||||
String shortcut = (this.shortcuts != null ? this.shortcuts[i - startIndex] : null);
|
||||
if (shortcut != null) {
|
||||
dependencyDescriptor = new ShortcutDependencyDescriptor(
|
||||
dependencyDescriptor, shortcut, beanClass);
|
||||
descriptor = new ShortcutDependencyDescriptor(descriptor, shortcut, registeredBean.getBeanClass());
|
||||
}
|
||||
ValueHolder argumentValue = argumentValues.getIndexedArgumentValue(i, null);
|
||||
resolved[i - startIndex] = resolveArgument(registeredBean,autowiredBeans,
|
||||
dependencyDescriptor, argumentValue);
|
||||
resolved[i - startIndex] = resolveArgument(registeredBean, descriptor, argumentValue, autowiredBeans);
|
||||
}
|
||||
registerDependentBeans(beanFactory, beanName, autowiredBeans);
|
||||
registerDependentBeans(registeredBean.getBeanFactory(), registeredBean.getBeanName(), autowiredBeans);
|
||||
|
||||
return AutowiredArguments.of(resolved);
|
||||
}
|
||||
|
||||
|
|
@ -277,15 +272,14 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
|||
throw new IllegalStateException("Unsupported executable: " + executable.getClass().getName());
|
||||
}
|
||||
|
||||
private ConstructorArgumentValues resolveArgumentValues(
|
||||
AbstractAutowireCapableBeanFactory beanFactory, String beanName,
|
||||
RootBeanDefinition mergedBeanDefinition) {
|
||||
|
||||
private ConstructorArgumentValues resolveArgumentValues(RegisteredBean registeredBean) {
|
||||
ConstructorArgumentValues resolved = new ConstructorArgumentValues();
|
||||
if (mergedBeanDefinition.hasConstructorArgumentValues()) {
|
||||
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
|
||||
if (beanDefinition.hasConstructorArgumentValues() &&
|
||||
registeredBean.getBeanFactory() instanceof AbstractAutowireCapableBeanFactory beanFactory) {
|
||||
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(
|
||||
beanFactory, beanName, mergedBeanDefinition, beanFactory.getTypeConverter());
|
||||
ConstructorArgumentValues values = mergedBeanDefinition.getConstructorArgumentValues();
|
||||
beanFactory, registeredBean.getBeanName(), beanDefinition, beanFactory.getTypeConverter());
|
||||
ConstructorArgumentValues values = beanDefinition.getConstructorArgumentValues();
|
||||
values.getIndexedArgumentValues().forEach((index, valueHolder) -> {
|
||||
ValueHolder resolvedValue = resolveArgumentValue(valueResolver, valueHolder);
|
||||
resolved.addIndexedArgumentValue(index, resolvedValue);
|
||||
|
|
@ -298,30 +292,27 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
|
|||
if (valueHolder.isConverted()) {
|
||||
return valueHolder;
|
||||
}
|
||||
Object resolvedValue = resolver.resolveValueIfNecessary("constructor argument",
|
||||
valueHolder.getValue());
|
||||
ValueHolder resolvedValueHolder = new ValueHolder(resolvedValue,
|
||||
valueHolder.getType(), valueHolder.getName());
|
||||
resolvedValueHolder.setSource(valueHolder);
|
||||
return resolvedValueHolder;
|
||||
Object value = resolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
|
||||
ValueHolder resolvedHolder = new ValueHolder(value, valueHolder.getType(), valueHolder.getName());
|
||||
resolvedHolder.setSource(valueHolder);
|
||||
return resolvedHolder;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object resolveArgument(RegisteredBean registeredBean, Set<String> autowiredBeans,
|
||||
DependencyDescriptor dependencyDescriptor, @Nullable ValueHolder argumentValue) {
|
||||
private Object resolveArgument(RegisteredBean registeredBean, DependencyDescriptor descriptor,
|
||||
@Nullable ValueHolder argumentValue, Set<String> autowiredBeans) {
|
||||
|
||||
TypeConverter typeConverter = registeredBean.getBeanFactory().getTypeConverter();
|
||||
Class<?> parameterType = dependencyDescriptor.getMethodParameter().getParameterType();
|
||||
if (argumentValue != null) {
|
||||
return (!argumentValue.isConverted()) ?
|
||||
typeConverter.convertIfNecessary(argumentValue.getValue(), parameterType) :
|
||||
argumentValue.getConvertedValue();
|
||||
return (argumentValue.isConverted() ? argumentValue.getConvertedValue() :
|
||||
typeConverter.convertIfNecessary(argumentValue.getValue(),
|
||||
descriptor.getDependencyType(), descriptor.getMethodParameter()));
|
||||
}
|
||||
try {
|
||||
return registeredBean.resolveAutowiredArgument(dependencyDescriptor, typeConverter, autowiredBeans);
|
||||
return registeredBean.resolveAutowiredArgument(descriptor, typeConverter, autowiredBeans);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
throw new UnsatisfiedDependencyException(null, registeredBean.getBeanName(), dependencyDescriptor, ex);
|
||||
throw new UnsatisfiedDependencyException(null, registeredBean.getBeanName(), descriptor, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -41,19 +41,6 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
|
|||
|
||||
private final ResolvableType payloadType;
|
||||
|
||||
/**
|
||||
* Create a new PayloadApplicationEvent.
|
||||
* @param source the object on which the event initially occurred (never {@code null})
|
||||
* @param payload the payload object (never {@code null})
|
||||
* @param payloadType the type object of payload object (can be {@code null})
|
||||
* @since 6.0
|
||||
*/
|
||||
public PayloadApplicationEvent(Object source, T payload, @Nullable ResolvableType payloadType) {
|
||||
super(source);
|
||||
Assert.notNull(payload, "Payload must not be null");
|
||||
this.payload = payload;
|
||||
this.payloadType = (payloadType != null) ? payloadType : ResolvableType.forInstance(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PayloadApplicationEvent, using the instance to infer its type.
|
||||
|
|
@ -64,6 +51,22 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
|
|||
this(source, payload, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PayloadApplicationEvent based on the provided payload type.
|
||||
* @param source the object on which the event initially occurred (never {@code null})
|
||||
* @param payload the payload object (never {@code null})
|
||||
* @param payloadType the type object of payload object (can be {@code null}).
|
||||
* Note that this is meant to indicate the payload type (e.g. {@code String}),
|
||||
* not the full event type (such as {@code PayloadApplicationEvent<<String>}).
|
||||
* @since 6.0
|
||||
*/
|
||||
public PayloadApplicationEvent(Object source, T payload, @Nullable ResolvableType payloadType) {
|
||||
super(source);
|
||||
Assert.notNull(payload, "Payload must not be null");
|
||||
this.payload = payload;
|
||||
this.payloadType = (payloadType != null ? payloadType : ResolvableType.forInstance(payload));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResolvableType getResolvableType() {
|
||||
|
|
|
|||
|
|
@ -128,12 +128,12 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
|
|||
|
||||
@Override
|
||||
public void multicastEvent(ApplicationEvent event) {
|
||||
multicastEvent(event, resolveDefaultEventType(event));
|
||||
multicastEvent(event, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
|
||||
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
|
||||
ResolvableType type = (eventType != null ? eventType : ResolvableType.forInstance(event));
|
||||
Executor executor = getTaskExecutor();
|
||||
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
|
||||
if (executor != null) {
|
||||
|
|
@ -145,10 +145,6 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
|
|||
}
|
||||
}
|
||||
|
||||
private ResolvableType resolveDefaultEventType(ApplicationEvent event) {
|
||||
return ResolvableType.forInstance(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the given listener with the given event.
|
||||
* @param listener the ApplicationListener to invoke
|
||||
|
|
|
|||
|
|
@ -385,23 +385,47 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
|
||||
/**
|
||||
* Publish the given event to all listeners.
|
||||
* <p>This is the internal delegate that all other {@code publishEvent}
|
||||
* methods refer to. It is not meant to be called directly but rather serves
|
||||
* as a propagation mechanism between application contexts in a hierarchy,
|
||||
* potentially overridden in subclasses for a custom propagation arrangement.
|
||||
* @param event the event to publish (may be an {@link ApplicationEvent}
|
||||
* or a payload object to be turned into a {@link PayloadApplicationEvent})
|
||||
* @param eventType the resolved event type, if known
|
||||
* @param typeHint the resolved event type, if known.
|
||||
* The implementation of this method also tolerates a payload type hint for
|
||||
* a payload object to be turned into a {@link PayloadApplicationEvent}.
|
||||
* However, the recommended way is to construct an actual event object via
|
||||
* {@link PayloadApplicationEvent#PayloadApplicationEvent(Object, Object, ResolvableType)}
|
||||
* instead for such scenarios.
|
||||
* @since 4.2
|
||||
* @see ApplicationEventMulticaster#multicastEvent(ApplicationEvent, ResolvableType)
|
||||
*/
|
||||
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
|
||||
protected void publishEvent(Object event, @Nullable ResolvableType typeHint) {
|
||||
Assert.notNull(event, "Event must not be null");
|
||||
ResolvableType eventType = null;
|
||||
|
||||
// Decorate event as an ApplicationEvent if necessary
|
||||
ApplicationEvent applicationEvent;
|
||||
if (event instanceof ApplicationEvent applEvent) {
|
||||
applicationEvent = applEvent;
|
||||
eventType = typeHint;
|
||||
}
|
||||
else {
|
||||
applicationEvent = new PayloadApplicationEvent<>(this, event, eventType);
|
||||
if (eventType == null) {
|
||||
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
|
||||
ResolvableType payloadType = null;
|
||||
if (typeHint != null && ApplicationEvent.class.isAssignableFrom(typeHint.toClass())) {
|
||||
eventType = typeHint;
|
||||
}
|
||||
else {
|
||||
payloadType = typeHint;
|
||||
}
|
||||
applicationEvent = new PayloadApplicationEvent<>(this, event, payloadType);
|
||||
}
|
||||
|
||||
// Determine event type only once (for multicast and parent publish)
|
||||
if (eventType == null) {
|
||||
eventType = ResolvableType.forInstance(applicationEvent);
|
||||
if (typeHint == null) {
|
||||
typeHint = eventType;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -416,7 +440,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
// Publish event via parent context as well...
|
||||
if (this.parent != null) {
|
||||
if (this.parent instanceof AbstractApplicationContext abstractApplicationContext) {
|
||||
abstractApplicationContext.publishEvent(event, eventType);
|
||||
abstractApplicationContext.publishEvent(event, typeHint);
|
||||
}
|
||||
else {
|
||||
this.parent.publishEvent(event);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.PayloadApplicationEvent;
|
||||
|
|
@ -68,16 +69,97 @@ class PayloadApplicationEventTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testEventClassWithPayloadType() {
|
||||
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(NumberHolderListener.class);
|
||||
|
||||
PayloadApplicationEvent<NumberHolder<Integer>> event = new PayloadApplicationEvent<>(this,
|
||||
new NumberHolder<>(42), ResolvableType.forClassWithGenerics(NumberHolder.class, Integer.class));
|
||||
ac.publishEvent(event);
|
||||
assertThat(ac.getBean(NumberHolderListener.class).events.contains(event.getPayload())).isTrue();
|
||||
ac.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testEventClassWithPayloadTypeOnParentContext() {
|
||||
ConfigurableApplicationContext parent = new AnnotationConfigApplicationContext(NumberHolderListener.class);
|
||||
ConfigurableApplicationContext ac = new GenericApplicationContext(parent);
|
||||
ac.refresh();
|
||||
|
||||
PayloadApplicationEvent<NumberHolder<Integer>> event = new PayloadApplicationEvent<>(this,
|
||||
new NumberHolder<>(42), ResolvableType.forClassWithGenerics(NumberHolder.class, Integer.class));
|
||||
ac.publishEvent(event);
|
||||
assertThat(parent.getBean(NumberHolderListener.class).events.contains(event.getPayload())).isTrue();
|
||||
ac.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testPayloadObjectWithPayloadType() {
|
||||
final Object payload = new NumberHolder<>(42);
|
||||
|
||||
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(NumberHolderListener.class) {
|
||||
@Override
|
||||
protected void finishRefresh() throws BeansException {
|
||||
super.finishRefresh();
|
||||
// This is not recommended: use publishEvent(new PayloadApplicationEvent(...)) instead
|
||||
publishEvent(payload, ResolvableType.forClassWithGenerics(NumberHolder.class, Integer.class));
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(ac.getBean(NumberHolderListener.class).events.contains(payload)).isTrue();
|
||||
ac.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testPayloadObjectWithPayloadTypeOnParentContext() {
|
||||
final Object payload = new NumberHolder<>(42);
|
||||
|
||||
ConfigurableApplicationContext parent = new AnnotationConfigApplicationContext(NumberHolderListener.class);
|
||||
ConfigurableApplicationContext ac = new GenericApplicationContext(parent) {
|
||||
@Override
|
||||
protected void finishRefresh() throws BeansException {
|
||||
super.finishRefresh();
|
||||
// This is not recommended: use publishEvent(new PayloadApplicationEvent(...)) instead
|
||||
publishEvent(payload, ResolvableType.forClassWithGenerics(NumberHolder.class, Integer.class));
|
||||
}
|
||||
};
|
||||
ac.refresh();
|
||||
|
||||
assertThat(parent.getBean(NumberHolderListener.class).events.contains(payload)).isTrue();
|
||||
ac.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testEventClassWithInterface() {
|
||||
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(AuditableListener.class);
|
||||
|
||||
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
||||
ac.publishEvent(event);
|
||||
assertThat(ac.getBean(AuditableListener.class).events.contains(event)).isTrue();
|
||||
ac.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testEventClassWithInterfaceOnParentContext() {
|
||||
ConfigurableApplicationContext parent = new AnnotationConfigApplicationContext(AuditableListener.class);
|
||||
ConfigurableApplicationContext ac = new GenericApplicationContext(parent);
|
||||
ac.refresh();
|
||||
|
||||
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
||||
ac.publishEvent(event);
|
||||
assertThat(parent.getBean(AuditableListener.class).events.contains(event)).isTrue();
|
||||
ac.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testProgrammaticEventListener() {
|
||||
|
|
@ -96,6 +178,27 @@ class PayloadApplicationEventTests {
|
|||
ac.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testProgrammaticEventListenerOnParentContext() {
|
||||
List<Auditable> events = new ArrayList<>();
|
||||
ApplicationListener<AuditablePayloadEvent<String>> listener = events::add;
|
||||
ApplicationListener<AuditablePayloadEvent<Integer>> mismatch = (event -> event.getPayload());
|
||||
|
||||
ConfigurableApplicationContext parent = new GenericApplicationContext();
|
||||
parent.addApplicationListener(listener);
|
||||
parent.addApplicationListener(mismatch);
|
||||
parent.refresh();
|
||||
ConfigurableApplicationContext ac = new GenericApplicationContext(parent);
|
||||
ac.refresh();
|
||||
|
||||
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
||||
ac.publishEvent(event);
|
||||
assertThat(events.contains(event)).isTrue();
|
||||
ac.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testProgrammaticPayloadListener() {
|
||||
|
|
@ -108,12 +211,77 @@ class PayloadApplicationEventTests {
|
|||
ac.addApplicationListener(mismatch);
|
||||
ac.refresh();
|
||||
|
||||
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
||||
ac.publishEvent(event);
|
||||
assertThat(events.contains(event.getPayload())).isTrue();
|
||||
String payload = "xyz";
|
||||
ac.publishEvent(payload);
|
||||
assertThat(events.contains(payload)).isTrue();
|
||||
ac.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testProgrammaticPayloadListenerOnParentContext() {
|
||||
List<String> events = new ArrayList<>();
|
||||
ApplicationListener<PayloadApplicationEvent<String>> listener = ApplicationListener.forPayload(events::add);
|
||||
ApplicationListener<PayloadApplicationEvent<Integer>> mismatch = ApplicationListener.forPayload(Integer::intValue);
|
||||
|
||||
ConfigurableApplicationContext parent = new GenericApplicationContext();
|
||||
parent.addApplicationListener(listener);
|
||||
parent.addApplicationListener(mismatch);
|
||||
parent.refresh();
|
||||
ConfigurableApplicationContext ac = new GenericApplicationContext(parent);
|
||||
ac.refresh();
|
||||
|
||||
String payload = "xyz";
|
||||
ac.publishEvent(payload);
|
||||
assertThat(events.contains(payload)).isTrue();
|
||||
ac.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testPlainPayloadListener() {
|
||||
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(PlainPayloadListener.class);
|
||||
|
||||
String payload = "xyz";
|
||||
ac.publishEvent(payload);
|
||||
assertThat(ac.getBean(PlainPayloadListener.class).events.contains(payload)).isTrue();
|
||||
ac.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
void testPlainPayloadListenerOnParentContext() {
|
||||
ConfigurableApplicationContext parent = new AnnotationConfigApplicationContext(PlainPayloadListener.class);
|
||||
ConfigurableApplicationContext ac = new GenericApplicationContext(parent);
|
||||
ac.refresh();
|
||||
|
||||
String payload = "xyz";
|
||||
ac.publishEvent(payload);
|
||||
assertThat(parent.getBean(PlainPayloadListener.class).events.contains(payload)).isTrue();
|
||||
ac.close();
|
||||
parent.close();
|
||||
}
|
||||
|
||||
|
||||
static class NumberHolder<T extends Number> {
|
||||
|
||||
public NumberHolder(T number) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
public static class NumberHolderListener {
|
||||
|
||||
public final List<NumberHolder<Integer>> events = new ArrayList<>();
|
||||
|
||||
@EventListener
|
||||
public void onEvent(NumberHolder<Integer> event) {
|
||||
events.add(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface Auditable {
|
||||
}
|
||||
|
|
@ -139,11 +307,16 @@ class PayloadApplicationEventTests {
|
|||
}
|
||||
}
|
||||
|
||||
static class NumberHolder<T extends Number> {
|
||||
|
||||
public NumberHolder(T number) {
|
||||
@Component
|
||||
public static class PlainPayloadListener {
|
||||
|
||||
public final List<String> events = new ArrayList<>();
|
||||
|
||||
@EventListener
|
||||
public void onEvent(String event) {
|
||||
events.add(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,9 @@ public abstract class AbstractApplicationContextTests extends AbstractListableBe
|
|||
|
||||
protected TestApplicationListener parentListener = new TestApplicationListener();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
public void setup() throws Exception {
|
||||
this.applicationContext = createContext();
|
||||
}
|
||||
|
||||
|
|
@ -79,6 +80,7 @@ public abstract class AbstractApplicationContextTests extends AbstractListableBe
|
|||
*/
|
||||
protected abstract ConfigurableApplicationContext createContext() throws Exception;
|
||||
|
||||
|
||||
@Test
|
||||
public void contextAwareSingletonWasCalledBack() throws Exception {
|
||||
ACATester aca = (ACATester) applicationContext.getBean("aca");
|
||||
|
|
|
|||
Loading…
Reference in New Issue