Add MessageHandlerMethodFactoryCreatingFactoryBean

Rework the logic around `ManagedList` in the `DefaultConfiguringBeanFactoryPostProcessor`
when it registers a `IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME` and
`IntegrationContextUtils.LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME` into a dedicated
`MessageHandlerMethodFactoryCreatingFactoryBean` with pure Java code instead of
`BeanDefinition` burden

* Deprecate `IntegrationContextUtils.DISPOSABLES_BEAN_NAME` constant for
already removed internal bean
* Align JVM args for Gradle with Java 17 on the `6.0` branch
This commit is contained in:
Artem Bilan
2021-11-29 12:49:29 -05:00
parent a843dae151
commit 8c85fc9957
4 changed files with 119 additions and 34 deletions

View File

@@ -1,5 +1,5 @@
version=5.5.7-SNAPSHOT
org.gradle.jvmargs=-Xms512m -Xmx4g -XX:MaxPermSize=1024m -XX:MaxMetaspaceSize=1g -Dkotlin.daemon.jvm.options="-Xmx1g --illegal-access=permit" -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx4g -Dkotlin.daemon.jvm.options="-Xmx1g --illegal-access=permit" -Dfile.encoding=UTF-8
org.gradle.caching=true
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false

View File

@@ -35,7 +35,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.log.LogAccessor;
import org.springframework.integration.channel.ChannelUtils;
@@ -46,14 +45,9 @@ import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.context.IntegrationProperties;
import org.springframework.integration.handler.LoggingHandler;
import org.springframework.integration.handler.support.CollectionArgumentResolver;
import org.springframework.integration.handler.support.MapArgumentResolver;
import org.springframework.integration.handler.support.PayloadExpressionArgumentResolver;
import org.springframework.integration.handler.support.PayloadsArgumentResolver;
import org.springframework.integration.json.JsonNodeWrapperToJsonNodeConverter;
import org.springframework.integration.json.JsonPathUtils;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.support.NullAwarePayloadArgumentResolver;
import org.springframework.integration.support.SmartLifecycleRoleController;
import org.springframework.integration.support.channel.BeanFactoryChannelResolver;
import org.springframework.integration.support.channel.ChannelResolverUtils;
@@ -61,7 +55,6 @@ import org.springframework.integration.support.converter.ConfigurableCompositeMe
import org.springframework.integration.support.converter.DefaultDatatypeChannelMessageConverter;
import org.springframework.integration.support.json.JacksonPresent;
import org.springframework.integration.support.utils.IntegrationUtils;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.ClassUtils;
@@ -483,32 +476,11 @@ public class DefaultConfiguringBeanFactoryPostProcessor
}
private static BeanDefinitionBuilder createMessageHandlerMethodFactoryBeanDefinition(boolean listCapable) {
return BeanDefinitionBuilder.genericBeanDefinition(DefaultMessageHandlerMethodFactory.class,
DefaultMessageHandlerMethodFactory::new)
.addPropertyReference("messageConverter",
IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME)
.addPropertyValue("customArgumentResolvers", buildArgumentResolvers(listCapable));
}
private static ManagedList<BeanDefinition> buildArgumentResolvers(boolean listCapable) {
ManagedList<BeanDefinition> resolvers = new ManagedList<>();
resolvers.add(new RootBeanDefinition(PayloadExpressionArgumentResolver.class));
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(NullAwarePayloadArgumentResolver.class);
builder.addConstructorArgReference(IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME);
// TODO Validator ?
resolvers.add(builder.getBeanDefinition());
resolvers.add(new RootBeanDefinition(PayloadsArgumentResolver.class));
if (listCapable) {
resolvers.add(
BeanDefinitionBuilder.genericBeanDefinition(CollectionArgumentResolver.class)
.addConstructorArgValue(true)
.getBeanDefinition());
}
resolvers.add(new RootBeanDefinition(MapArgumentResolver.class));
return resolvers;
return BeanDefinitionBuilder.genericBeanDefinition(MessageHandlerMethodFactoryCreatingFactoryBean.class,
() -> new MessageHandlerMethodFactoryCreatingFactoryBean(listCapable))
.addConstructorArgValue(listCapable)
.addPropertyReference("argumentResolverMessageConverter",
IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME);
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.handler.support.CollectionArgumentResolver;
import org.springframework.integration.handler.support.MapArgumentResolver;
import org.springframework.integration.handler.support.PayloadExpressionArgumentResolver;
import org.springframework.integration.handler.support.PayloadsArgumentResolver;
import org.springframework.integration.support.NullAwarePayloadArgumentResolver;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
/**
* The {@link FactoryBean} for creating integration-specific {@link MessageHandlerMethodFactory} instance.
* It adds these custom {@link HandlerMethodArgumentResolver}s in the order:
* <ul>
* <li>{@link PayloadExpressionArgumentResolver};
* <li>{@link NullAwarePayloadArgumentResolver};
* <li>{@link PayloadsArgumentResolver};
* <li>{@link CollectionArgumentResolver} if {@link #listCapable} is true;
* <li>{@link MapArgumentResolver}.
* </ul>
*
* @author Artyem Bilan
*
* @since 5.5.7
*/
class MessageHandlerMethodFactoryCreatingFactoryBean
implements FactoryBean<MessageHandlerMethodFactory>, BeanFactoryAware {
private final boolean listCapable;
MessageConverter argumentResolverMessageConverter;
private BeanFactory beanFactory;
MessageHandlerMethodFactoryCreatingFactoryBean(boolean listCapable) {
this.listCapable = listCapable;
}
public void setArgumentResolverMessageConverter(MessageConverter argumentResolverMessageConverter) {
this.argumentResolverMessageConverter = argumentResolverMessageConverter;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public Class<?> getObjectType() {
return MessageHandlerMethodFactory.class;
}
@Override
public MessageHandlerMethodFactory getObject() throws Exception {
DefaultMessageHandlerMethodFactory handlerMethodFactory = new DefaultMessageHandlerMethodFactory();
handlerMethodFactory.setBeanFactory(this.beanFactory);
handlerMethodFactory.setMessageConverter(this.argumentResolverMessageConverter);
handlerMethodFactory.setCustomArgumentResolvers(buildArgumentResolvers(this.listCapable));
handlerMethodFactory.afterPropertiesSet();
return handlerMethodFactory;
}
private List<HandlerMethodArgumentResolver> buildArgumentResolvers(boolean listCapable) throws Exception {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
resolvers.add(new PayloadExpressionArgumentResolver());
resolvers.add(new NullAwarePayloadArgumentResolver(this.argumentResolverMessageConverter));
resolvers.add(new PayloadsArgumentResolver());
if (listCapable) {
resolvers.add(new CollectionArgumentResolver(true));
}
resolvers.add(new MapArgumentResolver());
for (HandlerMethodArgumentResolver resolver : resolvers) {
if (resolver instanceof BeanFactoryAware) {
((BeanFactoryAware) resolver).setBeanFactory(this.beanFactory);
}
if (resolver instanceof InitializingBean) {
((InitializingBean) resolver).afterPropertiesSet();
}
}
return resolvers;
}
}

View File

@@ -110,6 +110,10 @@ public abstract class IntegrationContextUtils {
public static final String ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME =
"integrationArgumentResolverMessageConverter";
/**
* @deprecated since 5.5.7 - out of use.
*/
@Deprecated
public static final String DISPOSABLES_BEAN_NAME = "integrationDisposableAutoCreatedBeans";
public static final String MESSAGE_HANDLER_FACTORY_BEAN_NAME = "integrationMessageHandlerMethodFactory";