Add reflection hint on Publisher for bean destroy support
Prior to this commit, `DisposableBeanAdapter` supported reactive bean destroy methods by detected if `Publisher` is available on the classpath. The AOT engine did not contribute a reflection hint for this call. This commit ensures that this reflection hint is registered in all cases, even if there are no destroy methods detected on beans. Fixes gh-31278
This commit is contained in:
parent
d46c26d903
commit
a97ff39088
|
@ -35,6 +35,7 @@ import java.util.function.Predicate;
|
|||
import org.springframework.aot.generate.GeneratedMethods;
|
||||
import org.springframework.aot.hint.ExecutableMode;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
|
@ -128,6 +129,8 @@ class BeanDefinitionPropertiesCodeGenerator {
|
|||
|
||||
private void addInitDestroyMethods(Builder code, AbstractBeanDefinition beanDefinition,
|
||||
@Nullable String[] methodNames, String format) {
|
||||
// For Publisher-based destroy methods
|
||||
this.hints.reflection().registerType(TypeReference.of("org.reactivestreams.Publisher"));
|
||||
if (!ObjectUtils.isEmpty(methodNames)) {
|
||||
Class<?> beanType = ClassUtils.getUserClass(beanDefinition.getResolvableType().toClass());
|
||||
Arrays.stream(methodNames).forEach(methodName -> addInitDestroyHint(beanType, methodName));
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.lang.model.element.Modifier;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.aot.generate.GeneratedClass;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
|
@ -413,6 +414,7 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
|
|||
@Test
|
||||
void noDestroyMethod() {
|
||||
compile((beanDef, compiled) -> assertThat(beanDef.getDestroyMethodNames()).isNull());
|
||||
assertReflectionOnPublisher();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -420,6 +422,7 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
|
|||
beanDefinition.setDestroyMethodName("destroy");
|
||||
compile((beanDef, compiled) -> assertThat(beanDef.getDestroyMethodNames()).containsExactly("destroy"));
|
||||
assertHasMethodInvokeHints(InitDestroyBean.class, "destroy");
|
||||
assertReflectionOnPublisher();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -427,6 +430,7 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
|
|||
beanDefinition.setDestroyMethodName(privateDestroyMethod);
|
||||
compile((beanDef, compiled) -> assertThat(beanDef.getDestroyMethodNames()).containsExactly(privateDestroyMethod));
|
||||
assertHasMethodInvokeHints(InitDestroyBean.class, "privateDestroy");
|
||||
assertReflectionOnPublisher();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -434,6 +438,11 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
|
|||
beanDefinition.setDestroyMethodNames("destroy", privateDestroyMethod);
|
||||
compile((beanDef, compiled) -> assertThat(beanDef.getDestroyMethodNames()).containsExactly("destroy", privateDestroyMethod));
|
||||
assertHasMethodInvokeHints(InitDestroyBean.class, "destroy", "privateDestroy");
|
||||
assertReflectionOnPublisher();
|
||||
}
|
||||
|
||||
private void assertReflectionOnPublisher() {
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(Publisher.class)).accepts(generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue