From 85aca18327362a851da94a10819b337023aea6ec Mon Sep 17 00:00:00 2001
From: Fernando Blanch <ferblacar@gmail.com>
Date: Wed, 6 Nov 2024 19:18:54 +0100
Subject: [PATCH] Change order of the registry of sources classes after
 configuring Environment with all propertySources, so that sources classes can
 resolve conditions configurations. Fixes GH-3031

---
 .../stream/binder/DefaultBinderFactory.java   | 34 +++++++++----------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java b/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java
index a570741e7..c33b4abba 100644
--- a/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java
+++ b/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java
@@ -446,23 +446,6 @@ ConfigurableApplicationContext initializeBinderContextSimple(String configuratio
 			binderProducingContext.getBeanFactory().setConversionService(this.context.getBeanFactory().getConversionService());
 		}
 
-		List<Class> sourceClasses = new ArrayList<>();
-		sourceClasses.addAll(Arrays.asList(binderType.getConfigurationClasses()));
-		if (binderProperties.containsKey("spring.main.sources")) {
-			String sources = (String) binderProperties.get("spring.main.sources");
-			if (StringUtils.hasText(sources)) {
-				Stream.of(sources.split(",")).forEach(source -> {
-					try {
-						sourceClasses.add(Thread.currentThread().getContextClassLoader().loadClass(source.trim()));
-					}
-					catch (Exception e) {
-						throw new IllegalStateException("Failed to load class " + source, e);
-					}
-				});
-			}
-		}
-
-		binderProducingContext.register(sourceClasses.toArray(new Class[] {}));
 		MapPropertySource binderPropertySource = new MapPropertySource(configurationName, binderProperties);
 		binderProducingContext.getEnvironment().getPropertySources().addFirst(binderPropertySource);
 		binderProducingContext.setDisplayName(configurationName + "_context");
@@ -502,6 +485,23 @@ public void onApplicationEvent(ApplicationEvent event) {
 			}
 		}
 
+		// Register the sources classes to the specific binder context after configuring the environment property sources
+		List<Class> sourceClasses = new ArrayList<>(Arrays.asList(binderType.getConfigurationClasses()));
+		if (binderProperties.containsKey("spring.main.sources")) {
+			String sources = (String) binderProperties.get("spring.main.sources");
+			if (StringUtils.hasText(sources)) {
+				Stream.of(sources.split(",")).forEach(source -> {
+					try {
+						sourceClasses.add(Thread.currentThread().getContextClassLoader().loadClass(source.trim()));
+					}
+					catch (Exception e) {
+						throw new IllegalStateException("Failed to load class " + source, e);
+					}
+				});
+			}
+		}
+		binderProducingContext.register(sourceClasses.toArray(new Class[] {}));
+
 		if (refresh) {
 			if (!useApplicationContextAsParent || "integration".equals(binderType.getDefaultName())) {
 				this.propagateSharedBeans(binderProducingContext, (GenericApplicationContext) this.context);