Fix gateway proxy for generic interface in XML (#3935)
* Fix gateway proxy for generic interface in XML Without a `FactoryBean.OBJECT_TYPE_ATTRIBUTE` the application context cannot determine a qualified with generic an interface injection * Set back `FactoryBean.OBJECT_TYPE_ATTRIBUTE` in the `GatewayParser` when not in AOT mode. Set a `targetType` when used in AOT * * Remove unused import * * Fix `GatewayParserTests` for new code base
This commit is contained in:
@@ -23,7 +23,9 @@ import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.aot.AotDetector;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
@@ -253,8 +255,13 @@ public class GatewayParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
RootBeanDefinition beanDefinition = (RootBeanDefinition) gatewayProxyBuilder.getBeanDefinition();
|
||||
beanDefinition.setTargetType(
|
||||
ResolvableType.forClassWithGenerics(GatewayProxyFactoryBean.class, serviceInterface));
|
||||
if (AotDetector.useGeneratedArtifacts()) {
|
||||
beanDefinition.setTargetType(
|
||||
ResolvableType.forClassWithGenerics(GatewayProxyFactoryBean.class, serviceInterface));
|
||||
}
|
||||
else {
|
||||
beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, serviceInterface);
|
||||
}
|
||||
return new BeanDefinitionHolder(beanDefinition, id);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,12 +36,11 @@ import org.mockito.ArgumentMatchers;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -199,17 +198,17 @@ public class GatewayParserTests {
|
||||
@Test
|
||||
public void testFactoryBeanObjectTypeWithServiceInterface() {
|
||||
ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext) context).getBeanFactory();
|
||||
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition("&oneWay");
|
||||
ResolvableType resolvableType = beanDefinition.getResolvableType();
|
||||
assertThat(resolvableType.getGeneric(0).getRawClass()).isEqualTo(TestService.class);
|
||||
Object attribute =
|
||||
beanFactory.getMergedBeanDefinition("&oneWay").getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE);
|
||||
assertThat(attribute).isEqualTo(TestService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryBeanObjectTypeWithNoServiceInterface() {
|
||||
ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext) context).getBeanFactory();
|
||||
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition("&defaultConfig");
|
||||
ResolvableType resolvableType = beanDefinition.getResolvableType();
|
||||
assertThat(resolvableType.getGeneric(0).getRawClass()).isEqualTo(RequestReplyExchanger.class);
|
||||
Object attribute =
|
||||
beanFactory.getMergedBeanDefinition("&defaultConfig").getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE);
|
||||
assertThat(attribute).isEqualTo(RequestReplyExchanger.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<int:gateway service-interface="org.springframework.integration.gateway.GatewayXmlAndAnnotationTests.AGateway"
|
||||
<int:gateway service-interface="org.springframework.integration.gateway.GatewayXmlAndAnnotationTests$AGateway"
|
||||
default-reply-timeout="123" default-request-channel="nullChannel">
|
||||
<int:method name="explicitTimeoutShouldOverrideDefault" reply-timeout="456" />
|
||||
</int:gateway>
|
||||
|
||||
@@ -43,6 +43,9 @@ public class GatewayXmlAndAnnotationTests {
|
||||
@Autowired
|
||||
GatewayProxyFactoryBean<?> gatewayProxyFactoryBean;
|
||||
|
||||
@Autowired
|
||||
AGateway<String> stringAGateway;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(TestUtils.getPropertyValue(gatewayProxyFactoryBean, "defaultReplyTimeout", Expression.class)
|
||||
@@ -52,42 +55,44 @@ public class GatewayXmlAndAnnotationTests {
|
||||
"gatewayMap", Map.class);
|
||||
int assertions = 0;
|
||||
for (Entry<Method, MessagingGatewaySupport> entry : gatewayMap.entrySet()) {
|
||||
if (entry.getKey().getName().equals("annotationShouldntOverrideDefault")) {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(123L);
|
||||
assertions++;
|
||||
}
|
||||
else if (entry.getKey().getName().equals("annotationShouldOverrideDefault")) {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(234L);
|
||||
assertions++;
|
||||
}
|
||||
else if (entry.getKey().getName().equals("annotationShouldOverrideDefaultToInfinity")) {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(-1L);
|
||||
assertions++;
|
||||
}
|
||||
else if (entry.getKey().getName().equals("explicitTimeoutShouldOverrideDefault")) {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(456L);
|
||||
assertions++;
|
||||
switch (entry.getKey().getName()) {
|
||||
case "annotationShouldNotOverrideDefault" -> {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(123L);
|
||||
assertions++;
|
||||
}
|
||||
case "annotationShouldOverrideDefault" -> {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(234L);
|
||||
assertions++;
|
||||
}
|
||||
case "annotationShouldOverrideDefaultToInfinity" -> {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(-1L);
|
||||
assertions++;
|
||||
}
|
||||
case "explicitTimeoutShouldOverrideDefault" -> {
|
||||
assertThat(TestUtils.getPropertyValue(entry.getValue(),
|
||||
"replyTimeout")).isEqualTo(456L);
|
||||
assertions++;
|
||||
}
|
||||
}
|
||||
}
|
||||
assertThat(assertions).isEqualTo(4);
|
||||
}
|
||||
|
||||
public interface AGateway {
|
||||
public interface AGateway<T> {
|
||||
|
||||
@Gateway
|
||||
String annotationShouldntOverrideDefault(String foo);
|
||||
String annotationShouldNotOverrideDefault(T foo);
|
||||
|
||||
@Gateway(replyTimeout = 234)
|
||||
String annotationShouldOverrideDefault(String foo);
|
||||
String annotationShouldOverrideDefault(T foo);
|
||||
|
||||
@Gateway(replyTimeout = -1)
|
||||
String annotationShouldOverrideDefaultToInfinity(String foo);
|
||||
String annotationShouldOverrideDefaultToInfinity(T foo);
|
||||
|
||||
String explicitTimeoutShouldOverrideDefault(String foo);
|
||||
String explicitTimeoutShouldOverrideDefault(T foo);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user