From 9f4cced85f54cc779f5f6870308bfc0c612d5915 Mon Sep 17 00:00:00 2001 From: ferblaca Date: Tue, 17 Jun 2025 13:48:37 +0200 Subject: [PATCH] [kafka][metrics] Fix bean conditional resolution order to prioritize user-defined beans over binder's conditional beans in a multi-binder scenario This change modifies the loading order in DefaultBinderFactory.initializeBinderContextSimple to ensure that user configuration classes specified via spring.main.sources are loaded before binder configuration classes. This allows @ConditionalOnMissingBean annotations in the binder configurations to properly detect user-provided beans. Previously, when using KafkaBinderConfiguration with @ConditionalOnMissingBean(KafkaBinderMetrics.class), even if the user had configured a custom KafkaBinderMetrics bean via spring.main.sources, the condition would not work correctly because binder classes were loaded first. Fixes gh-3114 Signed-off-by: ferblaca --- .../cloud/stream/binder/DefaultBinderFactory.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 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 6a797914d0..5fffcc7ffc 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 @@ -510,8 +510,10 @@ public void onApplicationEvent(ApplicationEvent event) { } } - // Register the sources classes to the specific binder context after configuring the environment property sources - List sourceClasses = new ArrayList<>(Arrays.asList(binderType.getConfigurationClasses())); + // Modified registration: first user classes (spring.main.sources) and then binder classes + List sourceClasses = new ArrayList<>(); + + // First register user classes if defined in spring.main.sources if (binderProperties.containsKey("spring.main.sources")) { String sources = (String) binderProperties.get("spring.main.sources"); if (StringUtils.hasText(sources)) { @@ -525,6 +527,10 @@ public void onApplicationEvent(ApplicationEvent event) { }); } } + + // Then add binder configuration classes + sourceClasses.addAll(Arrays.asList(binderType.getConfigurationClasses())); + binderProducingContext.register(sourceClasses.toArray(new Class[] {})); if (refresh) {