Avoid eager creation of bound target beans
- At StreamListenerBeanPostProcessor, avoid eager creation of inbound/outbound target beans whenever possible - Use `applicationContext.getType(targetName)` instead of `applicationContext.getBean(targetName)` which checks the type of target beans from bean factory instead of creating the bean eagerly. - For declarative method invocation, `applicationContext.getBean` is needed as it requires the actual bean as its argument Resolves #767 Update the test - ignore bean definition not found exception when the bean definition doesn't exist
This commit is contained in:
committed by
Marius Bogoevici
parent
d250022250
commit
ba18c01602
@@ -30,10 +30,14 @@ import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerErrorMessages;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.annotation.Router;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.support.DefaultMessageBuilderFactory;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
@@ -84,7 +88,22 @@ public class StreamListenerHandlerMethodTests {
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(result.getPayload().toString().toUpperCase());
|
||||
assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStreamListenerMethodWithTargetBeanFromOutside() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestStreamListenerMethodWithTargetBeanFromOutside.class, "--server.port=0");
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
final String testMessageToSend = "testing";
|
||||
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
|
||||
DirectChannel directChannel = (DirectChannel) context.getBean(testMessageToSend.toUpperCase(), MessageChannel.class);
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<?> result = messageCollector.forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS);
|
||||
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessageToSend.toUpperCase());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -139,8 +158,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
fail("Exception expected on using invalid inbound name");
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
assertThat(e.getCause()).isInstanceOf(NoSuchBeanDefinitionException.class);
|
||||
assertThat(e.getCause()).hasMessageContaining("'invalid'");
|
||||
assertThat(e.getCause()).isInstanceOf(IllegalArgumentException.class);
|
||||
assertThat(e.getCause()).hasMessageContaining(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,6 +322,24 @@ public class StreamListenerHandlerMethodTests {
|
||||
}
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestStreamListenerMethodWithTargetBeanFromOutside {
|
||||
|
||||
private static final String ROUTER_QUEUE = "routeInstruction";
|
||||
|
||||
@StreamListener(Sink.INPUT)
|
||||
@SendTo(ROUTER_QUEUE)
|
||||
public Message<String> convertMessageBody(Message<String> message) {
|
||||
return new DefaultMessageBuilderFactory().withPayload(message.getPayload().toUpperCase()).build();
|
||||
}
|
||||
|
||||
@Router(inputChannel = ROUTER_QUEUE)
|
||||
public String route(String message) {
|
||||
return message.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
@EnableBinding({Sink.class})
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInvalidInputOnMethod {
|
||||
|
||||
@@ -20,13 +20,14 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerErrorMessages;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
@@ -57,9 +58,9 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
|
||||
public void testInputOutputArgsWithMoreParameters() {
|
||||
try {
|
||||
SpringApplication.run(TestInputOutputArgsWithMoreParameters.class, "--server.port=0");
|
||||
fail("Expected exception: "+ INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
fail("Expected exception: " + INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (BeanCreationException e) {
|
||||
assertThat(e.getMessage()).contains(INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
@@ -70,9 +71,9 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
|
||||
SpringApplication.run(TestInputOutputArgsWithInvalidBindableTarget.class, "--server.port=0");
|
||||
fail("Exception expected on using invalid bindable target as method parameter");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e.getCause()).isInstanceOf(NoSuchBeanDefinitionException.class);
|
||||
assertThat(e.getCause()).hasMessageContaining("'invalid'");
|
||||
catch (BeanCreationException e) {
|
||||
assertThat(e.getCause()).isInstanceOf(IllegalArgumentException.class);
|
||||
assertThat(e.getCause()).hasMessageContaining(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user