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

@@ -24,7 +24,7 @@ import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.MessagingAnnotationPostProcessor;
import org.springframework.integration.config.IntegrationRegistrar;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
@@ -38,6 +38,7 @@ import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.mock;
/**
* @author Mark Fisher
@@ -54,7 +55,7 @@ public class DirectChannelSubscriptionTests {
@BeforeEach
public void setupChannels() {
this.context.registerBean(MessagingAnnotationPostProcessor.class);
new IntegrationRegistrar().registerBeanDefinitions(mock(), this.context.getDefaultListableBeanFactory());
this.context.registerChannel("sourceChannel", this.sourceChannel);
this.context.registerChannel("targetChannel", this.targetChannel);
}

View File

@@ -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.
@@ -31,6 +31,7 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* @author Mark Fisher
@@ -42,8 +43,7 @@ public class ServiceActivatorAnnotationPostProcessorTests {
public void testAnnotatedMethod() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
try (TestApplicationContext context = TestUtils.createTestApplicationContext()) {
RootBeanDefinition postProcessorDef = new RootBeanDefinition(MessagingAnnotationPostProcessor.class);
context.registerBeanDefinition("postProcessor", postProcessorDef);
new IntegrationRegistrar().registerBeanDefinitions(mock(), context.getDefaultListableBeanFactory());
context.registerBeanDefinition("testChannel", new RootBeanDefinition(DirectChannel.class));
RootBeanDefinition beanDefinition = new RootBeanDefinition(SimpleServiceActivatorAnnotationTestBean.class);
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(latch);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 the original author or authors.
* Copyright 2017-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.
@@ -33,7 +33,6 @@ import org.mockito.ArgumentCaptor;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
@@ -103,9 +102,7 @@ public class CustomMessagingAnnotationTests {
public static class Config {
@Bean(name = IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME)
public static MessagingAnnotationPostProcessor messagingAnnotationPostProcessor(
ConfigurableListableBeanFactory beanFactory) {
public static MessagingAnnotationPostProcessor messagingAnnotationPostProcessor() {
MessagingAnnotationPostProcessor messagingAnnotationPostProcessor = new MessagingAnnotationPostProcessor();
messagingAnnotationPostProcessor.
addMessagingAnnotationPostProcessor(Logging.class, new LogAnnotationPostProcessor());

View File

@@ -27,8 +27,8 @@ import org.springframework.integration.annotation.Filter;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.IntegrationRegistrar;
import org.springframework.integration.config.MessagingAnnotationBeanPostProcessor;
import org.springframework.integration.config.MessagingAnnotationPostProcessor;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.test.util.TestUtils;
@@ -38,6 +38,7 @@ import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
/**
* @author Mark Fisher
@@ -56,7 +57,7 @@ public class FilterAnnotationPostProcessorTests {
@BeforeEach
public void init() {
this.context.registerBean(MessagingAnnotationPostProcessor.class);
new IntegrationRegistrar().registerBeanDefinitions(mock(), this.context.getDefaultListableBeanFactory());
this.context.registerChannel("input", this.inputChannel);
this.context.registerChannel("output", this.outputChannel);
}

View File

@@ -34,8 +34,8 @@ import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.IntegrationRegistrar;
import org.springframework.integration.config.MessagingAnnotationBeanPostProcessor;
import org.springframework.integration.config.MessagingAnnotationPostProcessor;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.support.MessageBuilder;
@@ -49,6 +49,7 @@ import org.springframework.messaging.core.DestinationResolver;
import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* @author Mark Fisher
@@ -59,10 +60,9 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void serviceActivatorAnnotation() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
context.registerChannel("inputChannel", inputChannel);
context.registerBean(MessagingAnnotationPostProcessor.class);
context.refresh();
MessagingAnnotationBeanPostProcessor postProcessor = context.getBean(MessagingAnnotationBeanPostProcessor.class);
@@ -134,8 +134,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void outboundOnlyServiceActivator() throws InterruptedException {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
context.registerChannel("testChannel", new DirectChannel());
CountDownLatch latch = new CountDownLatch(1);
OutboundOnlyTestBean testBean = new OutboundOnlyTestBean(latch);
@@ -144,16 +143,14 @@ public class MessagingAnnotationPostProcessorTests {
DestinationResolver<MessageChannel> channelResolver = new BeanFactoryChannelResolver(context);
MessageChannel testChannel = channelResolver.resolveDestination("testChannel");
testChannel.send(new GenericMessage<>("foo"));
latch.await(1000, TimeUnit.MILLISECONDS);
assertThat(latch.getCount()).isEqualTo(0);
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(testBean.getMessageText()).isEqualTo("foo");
context.close();
}
@Test
public void testChannelResolution() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel();
DirectChannel eventBus = new DirectChannel();
@@ -177,8 +174,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void testProxiedMessageEndpointAnnotation() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel();
context.registerChannel("inputChannel", inputChannel);
@@ -195,8 +191,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void testMessageEndpointAnnotationInherited() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel();
context.registerChannel("inputChannel", inputChannel);
@@ -211,8 +206,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void testMessageEndpointAnnotationInheritedWithProxy() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel();
context.registerChannel("inputChannel", inputChannel);
@@ -229,8 +223,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void testMessageEndpointAnnotationInheritedFromInterface() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel();
context.registerChannel("inputChannel", inputChannel);
@@ -245,8 +238,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void testMessageEndpointAnnotationInheritedFromInterfaceWithAutoCreatedChannels() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel();
context.registerChannel("inputChannel", inputChannel);
@@ -261,8 +253,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void testMessageEndpointAnnotationInheritedFromInterfaceWithProxy() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel();
context.registerChannel("inputChannel", inputChannel);
@@ -278,8 +269,7 @@ public class MessagingAnnotationPostProcessorTests {
@Test
public void testTransformer() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
context.registerBean(MessagingAnnotationPostProcessor.class);
TestApplicationContext context = createTestApplicationContext();
DirectChannel inputChannel = new DirectChannel();
context.registerChannel("inputChannel", inputChannel);
QueueChannel outputChannel = new QueueChannel();
@@ -298,6 +288,12 @@ public class MessagingAnnotationPostProcessorTests {
context.close();
}
private static TestApplicationContext createTestApplicationContext() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
new IntegrationRegistrar().registerBeanDefinitions(mock(), context.getDefaultListableBeanFactory());
return context;
}
@MessageEndpoint
public static class OutboundOnlyTestBean {

View File

@@ -27,13 +27,14 @@ import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.MessagingAnnotationPostProcessor;
import org.springframework.integration.config.IntegrationRegistrar;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.test.util.TestUtils.TestApplicationContext;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* @author Mark Fisher
@@ -56,7 +57,7 @@ public class RouterAnnotationPostProcessorTests {
@BeforeEach
public void init() {
this.context.registerBean(MessagingAnnotationPostProcessor.class);
new IntegrationRegistrar().registerBeanDefinitions(mock(), this.context.getDefaultListableBeanFactory());
context.registerChannel("input", inputChannel);
context.registerChannel("output", outputChannel);
context.registerChannel("routingChannel", routingChannel);

View File

@@ -25,7 +25,7 @@ import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.Splitter;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.MessagingAnnotationPostProcessor;
import org.springframework.integration.config.IntegrationRegistrar;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.test.util.TestUtils.TestApplicationContext;
@@ -33,6 +33,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* @author Mark Fisher
@@ -49,7 +50,7 @@ public class SplitterAnnotationPostProcessorTests {
@BeforeEach
public void init() {
this.context.registerBean(MessagingAnnotationPostProcessor.class);
new IntegrationRegistrar().registerBeanDefinitions(mock(), this.context.getDefaultListableBeanFactory());
this.context.registerChannel("input", this.inputChannel);
this.context.registerChannel("output", this.outputChannel);
}

View File

@@ -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.
@@ -29,7 +29,7 @@ import org.springframework.integration.MessageRejectedException;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.config.MessagingAnnotationPostProcessor;
import org.springframework.integration.config.IntegrationRegistrar;
import org.springframework.integration.dispatcher.RoundRobinLoadBalancingStrategy;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
@@ -37,6 +37,7 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.GenericMessage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* @author Mark Fisher
@@ -47,8 +48,7 @@ public class SubscriberOrderTests {
@Test
public void directChannelAndFailoverDispatcherWithSingleCallPerMethod() {
try (GenericApplicationContext context = TestUtils.createTestApplicationContext()) {
context.registerBeanDefinition("postProcessor",
new RootBeanDefinition(MessagingAnnotationPostProcessor.class));
new IntegrationRegistrar().registerBeanDefinitions(mock(), context.getDefaultListableBeanFactory());
RootBeanDefinition channelDefinition = new RootBeanDefinition(DirectChannel.class);
context.registerBeanDefinition("input", channelDefinition);
RootBeanDefinition testBeanDefinition = new RootBeanDefinition(TestBean.class);
@@ -75,8 +75,7 @@ public class SubscriberOrderTests {
@Test
public void directChannelAndFailoverDispatcherWithMultipleCallsPerMethod() {
try (GenericApplicationContext context = TestUtils.createTestApplicationContext()) {
context.registerBeanDefinition("postProcessor",
new RootBeanDefinition(MessagingAnnotationPostProcessor.class));
new IntegrationRegistrar().registerBeanDefinitions(mock(), context.getDefaultListableBeanFactory());
BeanDefinitionBuilder channelBuilder = BeanDefinitionBuilder.rootBeanDefinition(DirectChannel.class);
channelBuilder.addConstructorArgValue(null);
RootBeanDefinition channelDefinition = (RootBeanDefinition) channelBuilder.getBeanDefinition();
@@ -118,8 +117,7 @@ public class SubscriberOrderTests {
@Test
public void directChannelAndRoundRobinDispatcher() {
try (GenericApplicationContext context = TestUtils.createTestApplicationContext()) {
context.registerBeanDefinition("postProcessor",
new RootBeanDefinition(MessagingAnnotationPostProcessor.class));
new IntegrationRegistrar().registerBeanDefinitions(mock(), context.getDefaultListableBeanFactory());
RootBeanDefinition channelDefinition = new RootBeanDefinition(DirectChannel.class);
channelDefinition.getConstructorArgumentValues()
.addGenericArgumentValue(new RoundRobinLoadBalancingStrategy());