From a84a42188d9e92d329e33479ecfb619fbb25e987 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Wed, 5 Oct 2022 17:00:59 +0200 Subject: [PATCH] GH-2522 polishing previous commit --- .../stream/binder/DefaultBinderFactory.java | 155 +----------------- .../SpelExpressionConverterConfiguration.java | 11 +- 2 files changed, 11 insertions(+), 155 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 d787560f0..af88a14c9 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 @@ -36,13 +36,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.DisposableBean; -import org.springframework.boot.Banner.Mode; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.function.context.FunctionCatalog; import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry; import org.springframework.cloud.stream.config.ListenerContainerCustomizer; -import org.springframework.cloud.stream.config.SpelExpressionConverterConfiguration.SpelConverter; +import org.springframework.cloud.stream.config.SpelExpressionConverterConfiguration; import org.springframework.cloud.stream.reflection.GenericsUtils; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -56,7 +53,6 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.UrlResource; import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.messaging.MessageChannel; @@ -306,101 +302,16 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl .get(configurationName).getKey(); } - @SuppressWarnings("unused") - private ConfigurableApplicationContext initializeBinderContextBoot(String configurationName, Map binderProperties, - BinderType binderType, BinderConfiguration binderConfiguration) { - // Convert all properties to arguments, so that they receive maximum -// // precedence - ArrayList args = new ArrayList<>(); - for (Map.Entry property : binderProperties.entrySet()) { - args.add( - String.format("--%s=%s", property.getKey(), property.getValue())); - } - // Initialize the domain with a unique name based on the bootstrapping context - // setting - ConfigurableEnvironment environment = this.context != null - ? this.context.getEnvironment() : null; - String defaultDomain = environment != null - ? environment.getProperty("spring.jmx.default-domain") : ""; - args.add("--spring.jmx.default-domain=" + defaultDomain + "binder." - + configurationName); - - SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder( - binderType.getConfigurationClasses()) - .bannerMode(Mode.OFF).logStartupInfo(false) - .web(WebApplicationType.NONE); - // If the environment is not customized and a main context is available, we - // will set the latter as parent. - // This ensures that the defaults and user-defined customizations (e.g. custom - // connection factory beans) - // are propagated to the binder context. If the environment is customized, - // then the binder context should - // not inherit any beans from the parent - boolean useApplicationContextAsParent = binderProperties.isEmpty() - && this.context != null; - - if (useApplicationContextAsParent) { - springApplicationBuilder.parent(this.context); - } - else { - this.customizeParentChildContextRelationship(springApplicationBuilder, this.context); - springApplicationBuilder.listeners(new ApplicationListener() { - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (context != null) { - try { - context.publishEvent(event); - } - catch (Exception e) { - logger.warn("Failed to publish " + event, e); - } - } - } - }); - } - // If the current application context is not set as parent and the environment - // is set, - // provide the current context as an additional bean in the BeanFactory. - if (environment != null && !useApplicationContextAsParent) { - springApplicationBuilder - .initializers(new InitializerWithOuterContext(this.context)); - } - - if (environment != null && (useApplicationContextAsParent - || binderConfiguration.isInheritEnvironment())) { - StandardEnvironment binderEnvironment = new StandardEnvironment(); - binderEnvironment.merge(environment); - // See ConfigurationPropertySources.ATTACHED_PROPERTY_SOURCE_NAME - binderEnvironment.getPropertySources().remove("configurationProperties"); - /* - * Ensure that the web mode is set to NONE despite what the - * parent application context says. - * https://github.com/spring-cloud/spring-cloud-stream/issues/1708 - */ - binderEnvironment.getPropertySources() - .addFirst(new MapPropertySource("defaultBinderFactoryProperties", - Collections.singletonMap("spring.main.web-application-type", "NONE"))); - - springApplicationBuilder.environment(binderEnvironment); - } - - ConfigurableApplicationContext binderProducingContext = springApplicationBuilder - .run(args.toArray(new String[0])); - return binderProducingContext; - } - @SuppressWarnings("rawtypes") private ConfigurableApplicationContext initializeBinderContextSimple(String configurationName, Map binderProperties, BinderType binderType, BinderConfiguration binderConfiguration) { - //======= NEW CODE - AnnotationConfigApplicationContext binderProducingContext = new AnnotationConfigApplicationContext(); if (this.context != null) { binderProducingContext.getBeanFactory().setConversionService(this.context.getBeanFactory().getConversionService()); } - List sourceClasses = new ArrayList<>(); sourceClasses.addAll(Arrays.asList(binderType.getConfigurationClasses())); + sourceClasses.addAll(Collections.singletonList(SpelExpressionConverterConfiguration.class)); if (binderProperties.containsKey("spring.main.sources")) { String sources = (String) binderProperties.get("spring.main.sources"); if (StringUtils.hasText(sources)) { @@ -429,26 +340,6 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl else if (this.context != null) { this.propagateSharedBeans(binderProducingContext); Map customizers = this.context.getBeansOfType(ListenerContainerCustomizer.class); - if (!CollectionUtils.isEmpty(customizers)) { - for (Entry customizerEntry : customizers.entrySet()) { - ListenerContainerCustomizer customizerWrapper = new ListenerContainerCustomizer() { - @SuppressWarnings("unchecked") - @Override - public void configure(Object container, String destinationName, String group) { - try { - customizerEntry.getValue().configure(container, destinationName, group); - } - catch (Exception e) { - logger.warn("Failed while applying ListenerContainerCustomizer. In situations when multiple " - + "binders are used this is expected, since a particular customizer may not be applicable."); - } - } - }; - - ((GenericApplicationContext) binderProducingContext).registerBean(customizerEntry.getKey(), - ListenerContainerCustomizer.class, () -> customizerWrapper); - } - } binderProducingContext.addApplicationListener(new ApplicationListener() { @Override public void onApplicationEvent(ApplicationEvent event) { @@ -523,48 +414,6 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl } } - /** - * Creates a bare minimum application context that can be initialized by AOT. - * - * @param configurationName binder configuration name - * @param binderProperties binder properties - * @param binderConfiguration binder configuration - * @return a binder child application context suitable for AOT initialization ->>>>>>> 80e1e37a3... GH-2522 Add support for propagating select beans across child AC - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void customizeParentChildContextRelationship(SpringApplicationBuilder applicationBuilder, ApplicationContext context) { - if (context != null) { - Map customizers = context.getBeansOfType(ListenerContainerCustomizer.class); - applicationBuilder.initializers(childContext -> { - if (!CollectionUtils.isEmpty(customizers)) { - for (Entry customizerEntry : customizers.entrySet()) { - ListenerContainerCustomizer customizerWrapper = new ListenerContainerCustomizer() { - @Override - public void configure(Object container, String destinationName, String group) { - try { - customizerEntry.getValue().configure(container, destinationName, group); - } - catch (Exception e) { - logger.warn("Failed while applying ListenerContainerCustomizer. In situations when multiple " - + "binders are used this is expected, since a particular customizer may not be applicable" - + "to a particular binder. Customizer: " + customizerEntry.getValue() - + " Binder: " + childContext.getBean(AbstractMessageChannelBinder.class), e); - } - } - }; - - ((GenericApplicationContext) childContext).registerBean(customizerEntry.getKey(), - ListenerContainerCustomizer.class, () -> customizerWrapper); - } - } - GenericConversionService cs = (GenericConversionService) ((GenericApplicationContext) childContext).getBeanFactory().getConversionService(); - SpelConverter spelConverter = new SpelConverter(); - cs.addConverter(spelConverter); - }); - } - } - /** * Ensures that nested properties are flattened (i.e., foo.bar=baz instead of * foo={bar=baz}). diff --git a/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java b/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java index 9f1a600a2..4b90f7680 100644 --- a/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java +++ b/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/SpelExpressionConverterConfiguration.java @@ -22,11 +22,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Role; import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.ParseException; @@ -67,8 +69,13 @@ public class SpelExpressionConverterConfiguration { @Bean @ConfigurationPropertiesBinding @IntegrationConverter - public Converter spelConverter() { - return new SpelConverter(); + public Converter spelConverter(ConfigurableApplicationContext context) { + SpelConverter converter = new SpelConverter(); + ConfigurableConversionService cs = (ConfigurableConversionService) context.getBeanFactory().getConversionService(); + if (cs != null) { + cs.addConverter(converter); + } + return converter; } /**