Skip to content

Commit a28f5b6

Browse files
artembilangaryrussell
authored andcommitted
GH-3253: Scan BF hierarchy for BeanDefinition
Fixes #3253 The `IntegrationFlowBeanPostProcessor` uses a `containsBean()` and then `getBeanDefinition()` to be sure that we don't override already existing bean even if it is created in the parent(s) context. The problem that `containsBean()` check the hierarchy, but `getBeanDefinition()` doesn't. So, we fail with `NoSuchBeanDefinitionException` if bean exists in the parent ctx * Introduce an utility `IntegrationContextUtils.getBeanDefinition()` to scan `BeanFactory` recursively for `BeanDefinition` for the requested `name` * Use this tool in the `IntegrationFlowBeanPostProcessor` logic **Cherry-pick to 5.2.x & 5.1.x**
1 parent 8075e15 commit a28f5b6

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,9 @@
1919
import java.util.Properties;
2020

2121
import org.springframework.beans.factory.BeanFactory;
22+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
23+
import org.springframework.beans.factory.config.BeanDefinition;
24+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2225
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2326
import org.springframework.beans.factory.support.RootBeanDefinition;
2427
import org.springframework.expression.spel.support.SimpleEvaluationContext;
@@ -214,4 +217,26 @@ public static Properties getIntegrationProperties(BeanFactory beanFactory) {
214217
return properties;
215218
}
216219

220+
/**
221+
* Return a {@link BeanDefinition} with the given name,
222+
* obtained from the given {@link BeanFactory} or one of its parents.
223+
* @param name the bean name to return
224+
* @param beanFactory the {@link ConfigurableListableBeanFactory} to travers.
225+
* @return the {@link BeanDefinition} for a given name
226+
* @throws NoSuchBeanDefinitionException if a {@link BeanDefinition} is not found
227+
* @since 5.1.10
228+
*/
229+
public static BeanDefinition getBeanDefinition(String name, ConfigurableListableBeanFactory beanFactory) {
230+
try {
231+
return beanFactory.getBeanDefinition(name);
232+
}
233+
catch (NoSuchBeanDefinitionException ex) {
234+
BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
235+
if (parentBeanFactory instanceof ConfigurableListableBeanFactory) {
236+
return getBeanDefinition(name, (ConfigurableListableBeanFactory) parentBeanFactory);
237+
}
238+
throw ex;
239+
}
240+
}
241+
217242
}

spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2019 the original author or authors.
2+
* Copyright 2016-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -56,6 +56,7 @@
5656
import org.springframework.integration.config.ConsumerEndpointFactoryBean;
5757
import org.springframework.integration.config.IntegrationConfigUtils;
5858
import org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean;
59+
import org.springframework.integration.context.IntegrationContextUtils;
5960
import org.springframework.integration.core.MessageSource;
6061
import org.springframework.integration.dsl.ComponentsRegistration;
6162
import org.springframework.integration.dsl.ConsumerEndpointSpec;
@@ -282,7 +283,9 @@ else if (component instanceof AnnotationGatewayProxyFactoryBean) {
282283
String beanNameToUse = entry.getValue();
283284
if (StringUtils.hasText(beanNameToUse) &&
284285
ConfigurableBeanFactory.SCOPE_PROTOTYPE.equals(
285-
this.beanFactory.getBeanDefinition(beanNameToUse).getScope())) {
286+
IntegrationContextUtils.getBeanDefinition(beanNameToUse, this.beanFactory)
287+
.getScope())) {
288+
286289
this.beanFactory.initializeBean(componentToUse, beanNameToUse);
287290
}
288291
targetIntegrationComponents.put(component, beanNameToUse);
@@ -392,7 +395,8 @@ private boolean noBeanPresentForComponent(Object instance, String parentBeanName
392395
String beanName = ((NamedComponent) instance).getBeanName();
393396
if (beanName != null) {
394397
if (this.beanFactory.containsBean(beanName)) {
395-
BeanDefinition existingBeanDefinition = this.beanFactory.getBeanDefinition(beanName);
398+
BeanDefinition existingBeanDefinition =
399+
IntegrationContextUtils.getBeanDefinition(beanName, this.beanFactory);
396400
if (!ConfigurableBeanFactory.SCOPE_PROTOTYPE.equals(existingBeanDefinition.getScope())
397401
&& !instance.equals(this.beanFactory.getBean(beanName))) {
398402

0 commit comments

Comments
 (0)