INT-3701: Assist Boot with GPFB Type Determination
JIRA: https://jira.spring.io/browse/INT-3701 Allow Spring Boot to determine type created by GatewayProxyFactoryBean Spring Boot's @ConditionalOnBean can be used to activate some configuration when a bean of a particular type is present in the application context. To avoid early initialization, the search for beans is performed without instantiating them, i.e. it relies on the information that's available from the bean's class and its bean definition. This causes a problem with GatewayProxyFactoryBean as its a FactoryBean<Object> so Boot's best guess is that the bean that's produced by the factory will be an Object. For cases where the bean's type signiture does not contain enougn information to determine its type, Boot looks at an attribute, factoryBeanObjectType, on the factory bean's definition. The value of this attribute can be a Class or a String class name. This commit updates MessagingGatewayRegistrar to set the value of factoryBeanObjectType attribute to be the configured service interface for the gateway.
This commit is contained in:
committed by
Gary Russell
parent
15150ac499
commit
2653ce9aed
@@ -34,6 +34,9 @@ public final class IntegrationConfigUtils {
|
||||
|
||||
public static final String HANDLER_ALIAS_SUFFIX = ".handler";
|
||||
|
||||
// TODO: Boot constant - move to Spring Framework?
|
||||
public static final String FACTORY_BEAN_OBJECT_TYPE = "factoryBeanObjectType";
|
||||
|
||||
public static void registerSpelFunctionBean(BeanDefinitionRegistry registry, String functionId, String className,
|
||||
String methodSignature) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SpelFunctionFactoryBean.class)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2015 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.
|
||||
@@ -23,12 +23,11 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanMetadataAttribute;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
@@ -53,12 +52,11 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
* @author Andy Wilksinson
|
||||
* @since 4.0
|
||||
*/
|
||||
public class MessagingGatewayRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(MessagingGatewayRegistrar.class);
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
if (importingClassMetadata != null && importingClassMetadata.isAnnotated(MessagingGateway.class.getName())) {
|
||||
@@ -163,7 +161,11 @@ public class MessagingGatewayRegistrar implements ImportBeanDefinitionRegistrar
|
||||
|
||||
gatewayProxyBuilder.addConstructorArgValue(serviceInterface);
|
||||
|
||||
return new BeanDefinitionHolder(gatewayProxyBuilder.getBeanDefinition(), id);
|
||||
AbstractBeanDefinition beanDefinition = gatewayProxyBuilder.getBeanDefinition();
|
||||
beanDefinition.addMetadataAttribute(new BeanMetadataAttribute(IntegrationConfigUtils.FACTORY_BEAN_OBJECT_TYPE,
|
||||
serviceInterface));
|
||||
|
||||
return new BeanDefinitionHolder(beanDefinition, id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
reactor-environment="reactorEnvironment"/>
|
||||
|
||||
<!-- no assertions for this. The fact that this config does not result in error is sufficient -->
|
||||
<gateway default-request-channel="nullChannel"/>
|
||||
<gateway id="defaultConfig" default-request-channel="nullChannel"/>
|
||||
|
||||
<beans:bean id="testExecutor" class="org.springframework.integration.config.xml.GatewayParserTests$TestExecutor"/>
|
||||
|
||||
|
||||
@@ -30,8 +30,12 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.integration.config.IntegrationConfigUtils;
|
||||
import org.springframework.integration.gateway.RequestReplyExchanger;
|
||||
import org.springframework.integration.gateway.TestService;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
@@ -105,6 +109,22 @@ public class GatewayParserTests {
|
||||
assertNull(TestUtils.getPropertyValue(service, "asyncExecutor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryBeanObjectTypeWithServiceInterface() throws Exception {
|
||||
ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext)context).getBeanFactory();
|
||||
Object attribute = beanFactory.getMergedBeanDefinition("&oneWay").getAttribute(
|
||||
IntegrationConfigUtils.FACTORY_BEAN_OBJECT_TYPE);
|
||||
assertEquals(TestService.class.getName(), attribute);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryBeanObjectTypeWithNoServiceInterface() throws Exception {
|
||||
ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext)context).getBeanFactory();
|
||||
Object attribute = beanFactory.getMergedBeanDefinition("&defaultConfig").getAttribute(
|
||||
IntegrationConfigUtils.FACTORY_BEAN_OBJECT_TYPE);
|
||||
assertEquals(RequestReplyExchanger.class.getName(), attribute);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPromiseGateway() throws Exception {
|
||||
PollableChannel requestChannel = context.getBean("requestChannel", PollableChannel.class);
|
||||
|
||||
Reference in New Issue
Block a user