GH-8703: Fix MessagingAnnotationPP for AOT

Fixes https://github.com/spring-projects/spring-integration/issues/8703

* Instantiate a `MessagingAnnotationBeanPostProcessor` via factory method from `MessagingAnnotationPostProcessor`
avoiding extra code generation on an explicitly provided complex `Map` for bean definition property
* Fix test to react properly to a new logic of `MessagingAnnotationBeanPostProcessor` bean registration
This commit is contained in:
EddieChoCho
2023-08-12 09:47:28 -04:00
committed by Artem Bilan
parent ba6d35d123
commit ef5db3059d
12 changed files with 74 additions and 72 deletions

View File

@@ -16,6 +16,8 @@
package org.springframework.integration.config;
import java.beans.Introspector;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -99,19 +101,28 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register {@link MessagingAnnotationPostProcessor} and
* {@link org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor},
* {@link MessagingAnnotationBeanPostProcessor},
* if necessary.
* Inject {@code defaultPublishedChannel} from provided {@link AnnotationMetadata}, if any.
* @param registry The {@link BeanDefinitionRegistry} to register additional {@link BeanDefinition}s.
* @see MessagingAnnotationPostProcessor#messagingAnnotationBeanPostProcessor()
*/
private void registerMessagingAnnotationPostProcessors(BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME)) {
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME,
builder.getBeanDefinition());
BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
.getBeanDefinition());
}
String beanName = Introspector.decapitalize(MessagingAnnotationBeanPostProcessor.class.getName());
if (!registry.containsBeanDefinition(beanName)) {
registry.registerBeanDefinition(beanName,
BeanDefinitionBuilder.genericBeanDefinition()
.setFactoryMethodOnBean("messagingAnnotationBeanPostProcessor",
IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
.getBeanDefinition());
}
}

View File

@@ -65,16 +65,13 @@ public class MessagingAnnotationBeanPostProcessor
private final List<Runnable> methodsToPostProcessAfterContextInitialization = new ArrayList<>();
private final BeanDefinitionRegistry registry;
private ConfigurableListableBeanFactory beanFactory;
private volatile boolean initialized;
public MessagingAnnotationBeanPostProcessor(BeanDefinitionRegistry registry,
public MessagingAnnotationBeanPostProcessor(
Map<Class<? extends Annotation>, MethodAnnotationPostProcessor<?>> postProcessors) {
this.registry = registry;
this.postProcessors = postProcessors;
}
@@ -187,13 +184,12 @@ public class MessagingAnnotationBeanPostProcessor
String endpointBeanName = generateBeanName(beanName, method, annotationType);
endpoint.setBeanName(endpointBeanName);
this.registry.registerBeanDefinition(endpointBeanName,
((BeanDefinitionRegistry) this.beanFactory).registerBeanDefinition(endpointBeanName,
new RootBeanDefinition((Class<AbstractEndpoint>) endpoint.getClass(), () -> endpoint));
this.beanFactory.getBean(endpointBeanName);
}
}
protected String generateBeanName(String originalBeanName, Method method,
Class<? extends Annotation> annotationType) {

View File

@@ -16,7 +16,6 @@
package org.springframework.integration.config;
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
@@ -29,7 +28,6 @@ import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
@@ -91,14 +89,6 @@ public class MessagingAnnotationPostProcessor implements BeanDefinitionRegistryP
.map(BeanFactoryAware.class::cast)
.forEach((processor) -> processor.setBeanFactory((BeanFactory) this.registry));
this.registry.registerBeanDefinition(
Introspector.decapitalize(MessagingAnnotationBeanPostProcessor.class.getName()),
BeanDefinitionBuilder.rootBeanDefinition(MessagingAnnotationBeanPostProcessor.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
.addConstructorArgValue(this.registry)
.addConstructorArgValue(this.postProcessors)
.getBeanDefinition());
String[] beanNames = registry.getBeanDefinitionNames();
for (String beanName : beanNames) {
@@ -111,6 +101,16 @@ public class MessagingAnnotationPostProcessor implements BeanDefinitionRegistryP
}
}
/**
* The factory method for {@link MessagingAnnotationBeanPostProcessor} based
* on the environment from this {@link MessagingAnnotationPostProcessor}.
* @return the {@link MessagingAnnotationBeanPostProcessor} instance based on {@link #postProcessors}.
* @since 6.2
*/
public MessagingAnnotationBeanPostProcessor messagingAnnotationBeanPostProcessor() {
return new MessagingAnnotationBeanPostProcessor(this.postProcessors);
}
private void processCandidate(String beanName, AnnotatedBeanDefinition beanDefinition) {
MethodMetadata methodMetadata = beanDefinition.getFactoryMethodMetadata();
MergedAnnotations annotations = methodMetadata.getAnnotations(); // NOSONAR