GH-2828: Custom binders not recognized by AOT
- 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 https://github.com/spring-cloud/spring-cloud-stream/issues/2828 Resolves #2834
This commit is contained in:
committed by
Oleg Zhurakousky
parent
4a4ce6975a
commit
b867311333
@@ -32,6 +32,8 @@ import org.springframework.beans.factory.aot.BeanRegistrationCode;
|
||||
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;
|
||||
@@ -107,8 +109,21 @@ public class BinderChildContextInitializer implements ApplicationContextAware, B
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -180,4 +195,17 @@ public class BinderChildContextInitializer implements ApplicationContextAware, B
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user