From 3a7a14140befab9334036db21123d930b7288c6d Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Fri, 5 Oct 2018 22:05:03 -0400 Subject: [PATCH] INT-4539: Fix Java DSL for prototype beans JIRA: https://jira.spring.io/browse/INT-4539 The `IntegrationFlowBeanPostProcessor` doesn't check for prototype beans and just override them in the application context with the singletons * Since we can't in the DSL understand if provided object is a prototype or not, we try to check for its bean definition by possible bean name. Use `NamedComponent` for possible bean name to check. * Remove `final` from the `IntegrationComponentSpec.get()` since its result is not visible for CGI proxies when it is declared as a `@Bean` and subsequent `getObject()` produces a new internal object * Verify prototype beans with new test in the `IntegrationFlowTests` **Cherry-pick to 5.0.x** --- .../dsl/IntegrationFlowBeanPostProcessor.java | 36 ++++++++-------- .../dsl/IntegrationComponentSpec.java | 9 +--- .../dsl/flows/IntegrationFlowTests.java | 41 +++++++++++++++++++ 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java index 2216f9ff17..974c467b7f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java @@ -160,11 +160,7 @@ public class IntegrationFlowBeanPostProcessor id = flowNamePrefix + id; } - Collection messageHandlers = - this.beanFactory.getBeansOfType(messageHandler.getClass(), false, false) - .values(); - - if (!messageHandlers.contains(messageHandler)) { + if (noBeanPresentForComponent(messageHandler)) { String handlerBeanName = generateBeanName(messageHandler, flowNamePrefix); registerComponent(messageHandler, handlerBeanName, flowBeanName); @@ -175,8 +171,7 @@ public class IntegrationFlowBeanPostProcessor targetIntegrationComponents.put(endpoint, id); } else { - Collection values = this.beanFactory.getBeansOfType(component.getClass(), false, false).values(); - if (!values.contains(component)) { + if (noBeanPresentForComponent(component)) { if (component instanceof AbstractMessageChannel) { String channelBeanName = ((AbstractMessageChannel) component).getComponentName(); if (channelBeanName == null) { @@ -213,10 +208,7 @@ public class IntegrationFlowBeanPostProcessor if (!CollectionUtils.isEmpty(componentsToRegister)) { componentsToRegister.entrySet() .stream() - .filter(o -> - !this.beanFactory.getBeansOfType(o.getKey().getClass(), false, false) - .values() - .contains(o.getKey())) + .filter(o -> noBeanPresentForComponent(o.getKey())) .forEach(o -> registerComponent(o.getKey(), generateBeanName(o.getKey(), flowNamePrefix, o.getValue(), @@ -236,9 +228,7 @@ public class IntegrationFlowBeanPostProcessor targetIntegrationComponents.put(pollingChannelAdapterFactoryBean, id); MessageSource messageSource = spec.get().getT2(); - if (!this.beanFactory.getBeansOfType(messageSource.getClass(), false, false) - .values() - .contains(messageSource)) { + if (noBeanPresentForComponent(messageSource)) { String messageSourceId = id + ".source"; if (messageSource instanceof NamedComponent && ((NamedComponent) messageSource).getComponentName() != null) { @@ -311,10 +301,7 @@ public class IntegrationFlowBeanPostProcessor componentsToRegister.entrySet() .stream() - .filter(component -> - !this.beanFactory.getBeansOfType(component.getKey().getClass(), false, false) - .values() - .contains(component.getKey())) + .filter(component -> noBeanPresentForComponent(component.getKey())) .forEach(component -> registerComponent(component.getKey(), generateBeanName(component.getKey(), component.getValue()))); @@ -355,6 +342,19 @@ public class IntegrationFlowBeanPostProcessor } } + private boolean noBeanPresentForComponent(Object instance) { + if (instance instanceof NamedComponent) { + String beanName = ((NamedComponent) instance).getComponentName(); + if (beanName != null) { + return !this.beanFactory.containsBean(beanName); + } + } + + Collection beans = this.beanFactory.getBeansOfType(instance.getClass(), false, false).values(); + + return !beans.contains(instance); + } + private void registerComponent(Object component, String beanName) { registerComponent(component, beanName, null); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java index 71bd0f8533..5b58ce103c 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java @@ -63,7 +63,7 @@ public abstract class IntegrationComponentSpec requestMessage) { + return requestMessage; + } + + }; + } + + @Bean + public IntegrationFlow flow1WithPrototypeHandler( + @Qualifier("myHandler") AbstractReplyProducingMessageHandler handler) { + return f -> f.handle(handler, e -> e.id("flow1WithPrototypeHandlerConsumer")); + } + + @Bean + public IntegrationFlow flow2WithPrototypeHandler( + @Qualifier("myHandler") AbstractReplyProducingMessageHandler handler) { + return f -> f.handle(handler, e -> e.id("flow2WithPrototypeHandlerConsumer")); + } + } @Service