Skip to content

Commit

Permalink
GH-2828: Custom binders not recognized by AOT
Browse files Browse the repository at this point in the history
 - When using multi-binders with custom binders and running in AOT mode,
   there is a regression that is causing some issues for propertly
   identifying the binders during the AOT phase. It forces the users
   to provide property in the form of `spring.cloud.stream.binders.binders...`
   Fixing this issue by properly binding the custom binders in BinderChildContextInitializer.

Resolves #2828

Resolves #2834
  • Loading branch information
sobychacko authored and olegz committed Oct 20, 2023
1 parent 4a4ce69 commit b867311
Showing 1 changed file with 29 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.cloud.stream.config.BinderProperties;
import org.springframework.cloud.stream.config.BindingServiceConfiguration;
import org.springframework.cloud.stream.config.BindingServiceProperties;
import org.springframework.context.ApplicationContext;
Expand Down Expand Up @@ -107,8 +109,21 @@ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registe

private BindingServiceProperties declaredBindersAsBindingServiceProperties() {
BindingServiceProperties bindingServiceProperties = new BindingServiceProperties();

// We only need to bind to a single property -- "binders" -- defined in BindingServiceProperties
// to retrieve the custom binders declared by the application.
// Therefore, we are binding to a custom type (DeclaredBinders) which only has this custom binders map property.
// If we bind to BindingServiceProperties directly, it tries to bind all the properties defined there which
// is unnecessary and may throw errors.
// For more details on why that is the case, see https://github.com/spring-cloud/spring-cloud-stream/issues/2799

// Moreover, we cannot bind directly to spring.cloud.stream.binders and use BindingServiceProperties
// because in that case, users have to specify custom binders like spring.cloud.stream.binders.binders..
// See https://github.com/spring-cloud/spring-cloud-stream/issues/2828 for more details on that.
DeclaredBinders declaredBinders = new DeclaredBinders();
Binder.get(this.context.getEnvironment())
.bind("spring.cloud.stream.binders", Bindable.ofInstance(bindingServiceProperties));
.bind(ConfigurationPropertyName.of("spring.cloud.stream"), Bindable.ofInstance(declaredBinders));
bindingServiceProperties.setBinders(declaredBinders.getBinders());
return bindingServiceProperties;
}

Expand Down Expand Up @@ -180,4 +195,17 @@ public void applyTo(GenerationContext generationContext, BeanRegistrationCode be
}
}

private static class DeclaredBinders {

Map<String, BinderProperties> binders = new HashMap<>();

public Map<String, BinderProperties> getBinders() {
return binders;
}

public void setBinders(Map<String, BinderProperties> binders) {
this.binders = binders;
}
}

}

0 comments on commit b867311

Please sign in to comment.