Fix too restrictive entity callback matching.
We now properly support generic entity callbacks defined via lambda declarations. Fixes #2822.
This commit is contained in:
@@ -33,9 +33,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.ResolvableTypeProvider;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -291,12 +289,9 @@ class EntityCallbackDiscoverer {
|
||||
static boolean supportsEvent(EntityCallback<?> callback, ResolvableType entityType,
|
||||
ResolvableType callbackType) {
|
||||
|
||||
ResolvableType callbackInstanceType = callback instanceof EntityCallbackAdapter<?> provider
|
||||
? provider.getResolvableType()
|
||||
: ResolvableType.forInstance(callback);
|
||||
|
||||
return supportsEvent(callbackInstanceType, entityType)
|
||||
&& callbackType.isAssignableFrom(callbackInstanceType);
|
||||
return callback instanceof EntityCallbackAdapter<?> provider
|
||||
? provider.supports(callbackType, entityType)
|
||||
: callbackType.isInstance(callback) && supportsEvent(ResolvableType.forInstance(callback), entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,12 +341,10 @@ class EntityCallbackDiscoverer {
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
private static record EntityCallbackAdapter<T>(EntityCallback<T> delegate, ResolvableType type)
|
||||
implements EntityCallback<T>, ResolvableTypeProvider {
|
||||
implements EntityCallback<T> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ResolvableType getResolvableType() {
|
||||
return type;
|
||||
boolean supports(ResolvableType callbackType, ResolvableType entityType) {
|
||||
return callbackType.isInstance(delegate) && supportsEvent(type, entityType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,8 +169,7 @@ class DefaultEntityCallbacksUnitTests {
|
||||
@Test // DATACMNS-1467
|
||||
void detectsMultipleCallbacksWithinOneClass() {
|
||||
|
||||
var ctx = new AnnotationConfigApplicationContext(
|
||||
MultipleCallbacksInOneClassConfig.class);
|
||||
var ctx = new AnnotationConfigApplicationContext(MultipleCallbacksInOneClassConfig.class);
|
||||
|
||||
var callbacks = new DefaultEntityCallbacks(ctx);
|
||||
|
||||
@@ -184,6 +183,17 @@ class DefaultEntityCallbacksUnitTests {
|
||||
assertThat(ctx.getBean("callbacks", MultipleCallbacks.class).invocations).containsExactly("save", "convert");
|
||||
}
|
||||
|
||||
@Test // GH-2822
|
||||
void genericCallbackDiscoveredForObjectDeclaration() {
|
||||
|
||||
var ctx = new AnnotationConfigApplicationContext(SomeConfiguration.class);
|
||||
var callbacks = new DefaultEntityCallbacks(ctx);
|
||||
|
||||
callbacks.callback(BeforeSaveCallback.class, new PersonDocument(null, "Walter", null));
|
||||
|
||||
assertThat(ctx.getBean(SomeConfiguration.class).invoked).isTrue();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MyConfig {
|
||||
|
||||
@@ -312,4 +322,18 @@ class DefaultEntityCallbacksUnitTests {
|
||||
|
||||
}
|
||||
|
||||
// GH-2822
|
||||
@Configuration
|
||||
static class SomeConfiguration {
|
||||
|
||||
boolean invoked = false;
|
||||
|
||||
@Bean
|
||||
BeforeSaveCallback<Object> someGenericCallback() {
|
||||
return it -> {
|
||||
this.invoked = true;
|
||||
return it;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user