diff --git a/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java b/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java index f2a4780f5..f20ddbd5d 100644 --- a/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java +++ b/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java @@ -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(EntityCallback delegate, ResolvableType type) - implements EntityCallback, ResolvableTypeProvider { + implements EntityCallback { - @NonNull - @Override - public ResolvableType getResolvableType() { - return type; + boolean supports(ResolvableType callbackType, ResolvableType entityType) { + return callbackType.isInstance(delegate) && supportsEvent(type, entityType); } } diff --git a/src/test/java/org/springframework/data/mapping/callback/DefaultEntityCallbacksUnitTests.java b/src/test/java/org/springframework/data/mapping/callback/DefaultEntityCallbacksUnitTests.java index 2c4dcc025..1c54ee2a1 100644 --- a/src/test/java/org/springframework/data/mapping/callback/DefaultEntityCallbacksUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/callback/DefaultEntityCallbacksUnitTests.java @@ -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 someGenericCallback() { + return it -> { + this.invoked = true; + return it; + }; + } + } }