From 3c541c52b4595efb9d44094ee857742766a6a639 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Wed, 21 Apr 2021 11:01:05 -0400 Subject: [PATCH] Make `@IntegrationConverter` Native compatible (#3551) * Make `@IntegrationConverter` Native compatible * Add `BASE_PACKAGE` into an `IntegrationContextUtils`; deprecate similar in the `IntegrationConfigUtils`. This fixes a package tangle between `config` and `context` * Move `ConverterRegistrar` and `CustomConversionServiceFactoryBean` into a `config` package since they are package protected and created their instances in the `IntegrationConverterInitializer` functional way instead of reflection * Use new `IntegrationContextUtils.BASE_PACKAGE` constant instead of deprecated one * Make `DefaultConfiguringBeanFactoryPostProcessor` `public` to make it available for Spring Native `trigger` option in the `@NativeHint` declaration * Simplify logic around `JsonPath` to just a `ClassUtils.isPresent()` * Move the `@IntegrationConverter` processing logic into the `ConverterRegistrar` to avoid reflection via `BeanDefinition` ctor arg manipulation * Move the reflection logic into a `ConverterParser` which, being a part of XML configuration, is not going to be compatible with native any way * Mark `JsonNodeWrapperToJsonNodeConverter` with an `@IntegrationConverter` since it is not registered via reflection any more * Expose `MicrometerMetricsCaptorRegistrar.METER_REGISTRY_PRESENT` and use it in the `IntegrationGraphServer` * Extract `UnmarshallingTransformer.MIME_MESSAGE_PRESENT` for less reflection at runtime * Use `null` for a `ClassLoader` arg in the `ClassUtils.isPresent()` relying on the default one internally * * Fix Checkstyle violations --- .../ConverterRegistrar.java | 42 ++++++++----- .../CustomConversionServiceFactoryBean.java | 4 +- ...ltConfiguringBeanFactoryPostProcessor.java | 44 +++++-------- .../config/IntegrationConfigUtils.java | 7 ++- .../IntegrationConverterInitializer.java | 62 +++---------------- .../config/IntegrationRegistrar.java | 4 +- .../integration/config/xml/ChainParser.java | 5 +- .../config/xml/ConverterParser.java | 45 +++++++++++--- .../DefaultInboundChannelAdapterParser.java | 16 ++--- .../config/xml/IntegrationNamespaceUtils.java | 6 +- .../context/IntegrationContextUtils.java | 8 ++- .../graph/IntegrationGraphServer.java | 20 +++--- .../JsonNodeWrapperToJsonNodeConverter.java | 2 + .../json/Jackson2JsonObjectMapper.java | 12 ++-- .../support/json/JacksonPresent.java | 8 +-- .../MicrometerMetricsCaptorRegistrar.java | 11 +++- .../support/utils/IntegrationUtils.java | 6 +- .../MapToObjectTransformerTests.java | 21 ++++--- .../http/config/HttpContextUtils.java | 9 ++- .../http/inbound/BaseHttpInboundEndpoint.java | 10 +-- .../monitor/IntegrationMBeanExporter.java | 21 +++---- ...etIntegrationConfigurationInitializer.java | 4 +- .../websocket/dsl/WebSocketDslTests.java | 12 ++-- .../transformer/UnmarshallingTransformer.java | 11 ++-- 24 files changed, 193 insertions(+), 197 deletions(-) rename spring-integration-core/src/main/java/org/springframework/integration/{context => config}/ConverterRegistrar.java (53%) rename spring-integration-core/src/main/java/org/springframework/integration/{context => config}/CustomConversionServiceFactoryBean.java (92%) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/context/ConverterRegistrar.java b/spring-integration-core/src/main/java/org/springframework/integration/config/ConverterRegistrar.java similarity index 53% rename from spring-integration-core/src/main/java/org/springframework/integration/context/ConverterRegistrar.java rename to spring-integration-core/src/main/java/org/springframework/integration/config/ConverterRegistrar.java index 4a2106f710..f8f7d95330 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/context/ConverterRegistrar.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/ConverterRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,15 @@ * limitations under the License. */ -package org.springframework.integration.context; +package org.springframework.integration.config; +import java.util.HashSet; import java.util.Set; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.core.convert.support.GenericConversionService; @@ -34,35 +36,45 @@ import org.springframework.util.Assert; * @author Oleg Zhurakousky * @author Mark Fisher * @author Gary Russell + * @author Artem Bilan + * * @since 2.0 */ -class ConverterRegistrar implements InitializingBean, BeanFactoryAware { +class ConverterRegistrar implements InitializingBean, ApplicationContextAware { - private final Set converters; + private final Set converters; - private BeanFactory beanFactory; + private ApplicationContext applicationContext; - ConverterRegistrar(Set converters) { + ConverterRegistrar() { + this(new HashSet<>()); + } + + ConverterRegistrar(Set converters) { this.converters = converters; } - @Override - public void setBeanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; } @Override public void afterPropertiesSet() { - Assert.notNull(this.beanFactory, "BeanFactory is required"); - ConversionService conversionService = IntegrationUtils.getConversionService(this.beanFactory); + ConversionService conversionService = IntegrationUtils.getConversionService(this.applicationContext); if (conversionService instanceof GenericConversionService) { - ConversionServiceFactory.registerConverters(this.converters, (GenericConversionService) conversionService); + registerConverters((GenericConversionService) conversionService); } else { - Assert.notNull(conversionService, "Failed to locate '" + IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME + "'"); + Assert.notNull(conversionService, + () -> "Failed to locate '" + IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME + "'"); } } + private void registerConverters(GenericConversionService conversionService) { + this.converters.addAll(this.applicationContext.getBeansWithAnnotation(IntegrationConverter.class).values()); + ConversionServiceFactory.registerConverters(this.converters, conversionService); + } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/context/CustomConversionServiceFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/CustomConversionServiceFactoryBean.java similarity index 92% rename from spring-integration-core/src/main/java/org/springframework/integration/context/CustomConversionServiceFactoryBean.java rename to spring-integration-core/src/main/java/org/springframework/integration/config/CustomConversionServiceFactoryBean.java index f67a8093f2..c724b38995 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/context/CustomConversionServiceFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/CustomConversionServiceFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.integration.context; +package org.springframework.integration.config; import org.springframework.context.support.ConversionServiceFactoryBean; import org.springframework.core.convert.ConversionService; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java index feed0e67d4..97b6e0a73f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java @@ -35,7 +35,6 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertiesFactoryBean; -import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; @@ -91,25 +90,21 @@ import org.springframework.util.StringUtils; * * @see IntegrationContextUtils */ -class DefaultConfiguringBeanFactoryPostProcessor +public class DefaultConfiguringBeanFactoryPostProcessor implements BeanFactoryPostProcessor, BeanClassLoaderAware, SmartInitializingSingleton { private static final LogAccessor LOGGER = new LogAccessor(DefaultConfiguringBeanFactoryPostProcessor.class); - private static final IntegrationConverterInitializer INTEGRATION_CONVERTER_INITIALIZER = - new IntegrationConverterInitializer(); - private static final Set REGISTRIES_PROCESSED = new HashSet<>(); - private static final Class XPATH_CLASS; - private static final Class JSON_PATH_CLASS; + private static final boolean JSON_PATH_PRESENT = ClassUtils.isPresent("com.jayway.jsonpath.JsonPath", null); static { Class xpathClass = null; try { - xpathClass = ClassUtils.forName(IntegrationConfigUtils.BASE_PACKAGE + ".xml.xpath.XPathUtils", + xpathClass = ClassUtils.forName(IntegrationContextUtils.BASE_PACKAGE + ".xml.xpath.XPathUtils", ClassUtils.getDefaultClassLoader()); } catch (@SuppressWarnings("unused") ClassNotFoundException e) { @@ -119,18 +114,6 @@ class DefaultConfiguringBeanFactoryPostProcessor finally { XPATH_CLASS = xpathClass; } - - Class jsonPathClass = null; - try { - jsonPathClass = ClassUtils.forName("com.jayway.jsonpath.JsonPath", ClassUtils.getDefaultClassLoader()); - } - catch (@SuppressWarnings("unused") ClassNotFoundException e) { - LOGGER.debug("The '#jsonPath' SpEL function cannot be registered: " + - "there is no jayway json-path.jar on the classpath."); - } - finally { - JSON_PATH_CLASS = jsonPathClass; - } } @@ -140,6 +123,9 @@ class DefaultConfiguringBeanFactoryPostProcessor private BeanDefinitionRegistry registry; + DefaultConfiguringBeanFactoryPostProcessor() { + } + @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; @@ -402,12 +388,15 @@ class DefaultConfiguringBeanFactoryPostProcessor private void jsonPath(int registryId) throws LinkageError { String jsonPathBeanName = "jsonPath"; - if (JSON_PATH_CLASS != null - && !this.beanFactory.containsBean(jsonPathBeanName) - && !REGISTRIES_PROCESSED.contains(registryId)) { - - IntegrationConfigUtils.registerSpelFunctionBean(this.registry, jsonPathBeanName, - JsonPathUtils.class, "evaluate"); + if (JSON_PATH_PRESENT) { + if (!this.beanFactory.containsBean(jsonPathBeanName) && !REGISTRIES_PROCESSED.contains(registryId)) { + IntegrationConfigUtils.registerSpelFunctionBean(this.registry, jsonPathBeanName, + JsonPathUtils.class, "evaluate"); + } + } + else { + LOGGER.debug("The '#jsonPath' SpEL function cannot be registered: " + + "there is no jayway json-path.jar on the classpath."); } } @@ -430,9 +419,6 @@ class DefaultConfiguringBeanFactoryPostProcessor IntegrationContextUtils.JSON_NODE_WRAPPER_TO_JSON_NODE_CONVERTER, new RootBeanDefinition(JsonNodeWrapperToJsonNodeConverter.class, JsonNodeWrapperToJsonNodeConverter::new)); - - INTEGRATION_CONVERTER_INITIALIZER.registerConverter(this.registry, - new RuntimeBeanReference(IntegrationContextUtils.JSON_NODE_WRAPPER_TO_JSON_NODE_CONVERTER)); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigUtils.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigUtils.java index c3c7c4b446..57433aaf99 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigUtils.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigUtils.java @@ -20,6 +20,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.integration.channel.DirectChannel; +import org.springframework.integration.context.IntegrationContextUtils; /** * Shared utility methods for Integration configuration. @@ -30,7 +31,11 @@ import org.springframework.integration.channel.DirectChannel; */ public final class IntegrationConfigUtils { - public static final String BASE_PACKAGE = "org.springframework.integration"; + /** + * @deprecated in favor of {@link IntegrationContextUtils#BASE_PACKAGE}. + */ + @Deprecated + public static final String BASE_PACKAGE = IntegrationContextUtils.BASE_PACKAGE; public static final String HANDLER_ALIAS_SUFFIX = ".handler"; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConverterInitializer.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConverterInitializer.java index ba00f65db4..83ec13505a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConverterInitializer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConverterInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +16,10 @@ package org.springframework.integration.config; -import java.util.Set; - -import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.ManagedSet; import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.MethodMetadata; import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.integration.support.utils.IntegrationUtils; @@ -40,56 +30,20 @@ import org.springframework.integration.support.utils.IntegrationUtils; */ public class IntegrationConverterInitializer implements IntegrationConfigurationInitializer { - private static final String CONTEXT_PACKAGE = "org.springframework.integration.context."; - @Override public void initialize(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; - for (String beanName : registry.getBeanDefinitionNames()) { - BeanDefinition beanDefinition = registry.getBeanDefinition(beanName); - if (beanDefinition instanceof AnnotatedBeanDefinition) { - AnnotationMetadata metadata = ((AnnotatedBeanDefinition) beanDefinition).getMetadata(); - boolean hasIntegrationConverter = metadata.hasAnnotation(IntegrationConverter.class.getName()); - - if (!hasIntegrationConverter && beanDefinition.getSource() instanceof MethodMetadata) { - MethodMetadata beanMethod = (MethodMetadata) beanDefinition.getSource(); - hasIntegrationConverter = beanMethod.isAnnotated(IntegrationConverter.class.getName()); // NOSONAR never null - } - - if (hasIntegrationConverter) { - this.registerConverter(registry, new RuntimeBeanReference(beanName)); - } - } - } - } - - @SuppressWarnings("unchecked") - public void registerConverter(BeanDefinitionRegistry registry, BeanMetadataElement converterBeanDefinition) { - Set converters = new ManagedSet(); if (!registry.containsBeanDefinition(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME)) { - BeanDefinitionBuilder converterRegistrarBuilder = BeanDefinitionBuilder.genericBeanDefinition( - CONTEXT_PACKAGE + "ConverterRegistrar").addConstructorArgValue(converters); registry.registerBeanDefinition(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME, - converterRegistrarBuilder.getBeanDefinition()); - - if (!registry.containsBeanDefinition(IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME)) { - registry.registerBeanDefinition(IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, - new RootBeanDefinition(CONTEXT_PACKAGE + "CustomConversionServiceFactoryBean")); - } - } - else { - BeanDefinition converterRegistrarBeanDefinition = registry - .getBeanDefinition(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME); - converters = (Set) converterRegistrarBeanDefinition - .getConstructorArgumentValues() - .getIndexedArgumentValues() - .values() - .iterator() - .next() - .getValue(); + new RootBeanDefinition(ConverterRegistrar.class, ConverterRegistrar::new)); } - converters.add(converterBeanDefinition); // NOSONAR never null + if (!registry.containsBeanDefinition(IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME)) { + registry.registerBeanDefinition(IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, + new RootBeanDefinition(CustomConversionServiceFactoryBean.class, + CustomConversionServiceFactoryBean::new)); + } } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationRegistrar.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationRegistrar.java index 06c780e173..9557ee234f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationRegistrar.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationRegistrar.java @@ -39,9 +39,7 @@ import org.springframework.util.ClassUtils; public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar { static { - if (ClassUtils.isPresent("org.springframework.integration.dsl.support.Function", - IntegrationRegistrar.class.getClassLoader())) { - + if (ClassUtils.isPresent("org.springframework.integration.dsl.support.Function", null)) { throw new ApplicationContextException("Starting with Spring Integration 5.0, " + "the 'spring-integration-java-dsl' dependency is no longer needed; " + "the Java DSL has been merged into the core project. " diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ChainParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ChainParser.java index e8520ebbfd..d19f82760f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ChainParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ChainParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.IntegrationConfigUtils; +import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.integration.handler.MessageHandlerChain; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; @@ -93,7 +94,7 @@ public class ChainParser extends AbstractConsumerEndpointParser { } if ("gateway".equals(child.getLocalName())) { BeanDefinitionBuilder gwBuilder = BeanDefinitionBuilder.genericBeanDefinition( - IntegrationConfigUtils.BASE_PACKAGE + ".gateway.RequestReplyMessageHandlerAdapter"); + IntegrationContextUtils.BASE_PACKAGE + ".gateway.RequestReplyMessageHandlerAdapter"); gwBuilder.addConstructorArgValue(childBeanMetadata); handlerList.add(gwBuilder.getBeanDefinition()); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ConverterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ConverterParser.java index 18f069f375..881e91afae 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ConverterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ConverterParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,21 @@ package org.springframework.integration.config.xml; +import java.util.Set; + import org.w3c.dom.Element; +import org.springframework.beans.BeanMetadataElement; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.ManagedSet; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.integration.config.IntegrationConverterInitializer; +import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -37,25 +43,50 @@ import org.springframework.util.StringUtils; */ public class ConverterParser extends AbstractBeanDefinitionParser { - private static final IntegrationConverterInitializer INTEGRATION_CONVERTER_INITIALIZER = - new IntegrationConverterInitializer(); - @Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionRegistry registry = parserContext.getRegistry(); BeanComponentDefinition converterDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext); if (converterDefinition != null) { - INTEGRATION_CONVERTER_INITIALIZER.registerConverter(registry, converterDefinition); + registerConverter(registry, converterDefinition); } else { String beanName = element.getAttribute("ref"); Assert.isTrue(StringUtils.hasText(beanName), "Either a 'ref' attribute pointing to a Converter " + "or a sub-element defining a Converter is required."); - INTEGRATION_CONVERTER_INITIALIZER.registerConverter(registry, new RuntimeBeanReference(beanName)); + registerConverter(registry, new RuntimeBeanReference(beanName)); } return null; } + @SuppressWarnings("unchecked") + private static void registerConverter(BeanDefinitionRegistry registry, + BeanMetadataElement converterBeanDefinition) { + + Set converters = new ManagedSet<>(); + if (!registry.containsBeanDefinition(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME)) { + BeanDefinitionBuilder converterRegistrarBuilder = + BeanDefinitionBuilder.genericBeanDefinition( + IntegrationContextUtils.BASE_PACKAGE + ".config.ConverterRegistrar") + .addConstructorArgValue(converters); + registry.registerBeanDefinition(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME, + converterRegistrarBuilder.getBeanDefinition()); + } + else { + BeanDefinition converterRegistrarBeanDefinition = registry + .getBeanDefinition(IntegrationContextUtils.CONVERTER_REGISTRAR_BEAN_NAME); + converters = (Set) converterRegistrarBeanDefinition + .getConstructorArgumentValues() + .getIndexedArgumentValues() + .values() + .iterator() + .next() + .getValue(); + } + + converters.add(converterBeanDefinition); // NOSONAR never null + } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java index 5aca12c723..eab8efe690 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultInboundChannelAdapterParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.ExpressionFactoryBean; -import org.springframework.integration.config.IntegrationConfigUtils; +import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.integration.endpoint.ExpressionEvaluatingMessageSource; import org.springframework.integration.endpoint.MethodInvokingMessageSource; import org.springframework.integration.expression.DynamicExpression; @@ -67,13 +67,13 @@ public class DefaultInboundChannelAdapterParser extends AbstractPollingInboundCh if (!hasInnerDef && !hasRef && !hasExpression && !hasScriptElement && !hasExpressionElement) { // NOSONAR parserContext.getReaderContext().error( - "Exactly one of the 'ref', 'expression', inner bean,