Skip to content

Commit bca9d27

Browse files
committed
Fix Gateway proxy registration for AOT
The `GatewayProxyInstantiationPostProcessor` does nothing on the AOT phase. Therefore, scanned and imported beans for `@MessagingGateway` are not decorated after AOT * Implement a `BeanRegistrationAotProcessor` in the `GatewayProxyInstantiationPostProcessor` to `RegisteredBean.getMergedBeanDefinition()` withe respective `AnnotationGatewayProxyFactoryBean` and its requirements for ctor arg and `targetType` * Scan for the `@MessagingGateway` bean in the `GatewayProxyInitializationAotProcessor` to register respective proxy hints
1 parent b80f107 commit bca9d27

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

spring-integration-core/src/main/java/org/springframework/integration/aot/GatewayProxyInitializationAotProcessor.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.Arrays;
2020
import java.util.List;
21+
import java.util.stream.Stream;
2122

2223
import org.springframework.aop.framework.AopProxyUtils;
2324
import org.springframework.aop.framework.ProxyFactoryBean;
@@ -26,12 +27,15 @@
2627
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
2728
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2829
import org.springframework.beans.factory.support.RegisteredBean;
30+
import org.springframework.core.annotation.AnnotatedElementUtils;
31+
import org.springframework.integration.annotation.MessagingGateway;
2932
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
3033
import org.springframework.integration.gateway.RequestReplyExchanger;
3134

35+
3236
/**
3337
* A {@link BeanFactoryInitializationAotProcessor} for registering proxy interfaces
34-
* of the {@link GatewayProxyFactoryBean} beans.
38+
* of the {@link GatewayProxyFactoryBean} beans or {@link MessagingGateway} interfaces.
3539
*
3640
* @author Artem Bilan
3741
*
@@ -41,13 +45,23 @@ class GatewayProxyInitializationAotProcessor implements BeanFactoryInitializatio
4145

4246
@Override
4347
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
44-
List<? extends Class<?>> gatewayProxyInterfaces =
48+
List<RegisteredBean> registeredBeans =
4549
Arrays.stream(beanFactory.getBeanDefinitionNames())
4650
.map((beanName) -> RegisteredBean.of(beanFactory, beanName))
47-
.filter((bean) -> ProxyFactoryBean.class.isAssignableFrom(bean.getBeanClass()))
48-
.map((bean) -> bean.getBeanType().getGeneric(0).resolve(RequestReplyExchanger.class))
4951
.toList();
5052

53+
Stream<Class<?>> gatewayProxyInterfaces =
54+
Stream.concat(
55+
registeredBeans.stream()
56+
.filter(bean -> ProxyFactoryBean.class.isAssignableFrom(bean.getBeanClass()))
57+
.map((bean) ->
58+
bean.getBeanType().getGeneric(0).resolve(RequestReplyExchanger.class)),
59+
registeredBeans.stream()
60+
.map(RegisteredBean::getBeanClass)
61+
.filter(beanClass ->
62+
beanClass.isInterface() &&
63+
AnnotatedElementUtils.hasAnnotation(beanClass, MessagingGateway.class)));
64+
5165
return (generationContext, beanFactoryInitializationCode) -> {
5266
ProxyHints proxyHints = generationContext.getRuntimeHints().proxies();
5367
gatewayProxyInterfaces.forEach((gatewayInterface) ->

spring-integration-core/src/main/java/org/springframework/integration/config/GatewayProxyInstantiationPostProcessor.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@
1818

1919
import org.springframework.beans.BeansException;
2020
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
21+
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
22+
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
2123
import org.springframework.beans.factory.config.BeanDefinition;
2224
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
2325
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
26+
import org.springframework.beans.factory.support.RegisteredBean;
27+
import org.springframework.beans.factory.support.RootBeanDefinition;
2428
import org.springframework.context.ApplicationContext;
2529
import org.springframework.context.ApplicationContextAware;
2630
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
31+
import org.springframework.core.ResolvableType;
2732
import org.springframework.core.annotation.AnnotatedElementUtils;
2833
import org.springframework.integration.annotation.MessagingGateway;
2934
import org.springframework.integration.gateway.AnnotationGatewayProxyFactoryBean;
@@ -39,7 +44,7 @@
3944
* @see AnnotationGatewayProxyFactoryBean
4045
*/
4146
class GatewayProxyInstantiationPostProcessor implements
42-
InstantiationAwareBeanPostProcessor, ApplicationContextAware {
47+
InstantiationAwareBeanPostProcessor, BeanRegistrationAotProcessor, ApplicationContextAware {
4348

4449
private final BeanDefinitionRegistry registry;
4550

@@ -77,4 +82,17 @@ public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName
7782
return null;
7883
}
7984

85+
@Override
86+
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
87+
Class<?> beanClass = registeredBean.getBeanClass();
88+
if (beanClass.isInterface() && AnnotatedElementUtils.hasAnnotation(beanClass, MessagingGateway.class)) {
89+
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
90+
beanDefinition.setBeanClass(AnnotationGatewayProxyFactoryBean.class);
91+
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanClass);
92+
beanDefinition.setTargetType(
93+
ResolvableType.forClassWithGenerics(AnnotationGatewayProxyFactoryBean.class, beanClass));
94+
}
95+
return null;
96+
}
97+
8098
}

0 commit comments

Comments
 (0)