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
This commit is contained in:
@@ -18,6 +18,7 @@ package org.springframework.integration.aot;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||
@@ -26,12 +27,15 @@ import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContrib
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
|
||||
import org.springframework.integration.gateway.RequestReplyExchanger;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link BeanFactoryInitializationAotProcessor} for registering proxy interfaces
|
||||
* of the {@link GatewayProxyFactoryBean} beans.
|
||||
* of the {@link GatewayProxyFactoryBean} beans or {@link MessagingGateway} interfaces.
|
||||
*
|
||||
* @author Artem Bilan
|
||||
*
|
||||
@@ -41,13 +45,23 @@ class GatewayProxyInitializationAotProcessor implements BeanFactoryInitializatio
|
||||
|
||||
@Override
|
||||
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
List<? extends Class<?>> gatewayProxyInterfaces =
|
||||
List<RegisteredBean> registeredBeans =
|
||||
Arrays.stream(beanFactory.getBeanDefinitionNames())
|
||||
.map((beanName) -> RegisteredBean.of(beanFactory, beanName))
|
||||
.filter((bean) -> ProxyFactoryBean.class.isAssignableFrom(bean.getBeanClass()))
|
||||
.map((bean) -> bean.getBeanType().getGeneric(0).resolve(RequestReplyExchanger.class))
|
||||
.toList();
|
||||
|
||||
Stream<Class<?>> gatewayProxyInterfaces =
|
||||
Stream.concat(
|
||||
registeredBeans.stream()
|
||||
.filter(bean -> ProxyFactoryBean.class.isAssignableFrom(bean.getBeanClass()))
|
||||
.map((bean) ->
|
||||
bean.getBeanType().getGeneric(0).resolve(RequestReplyExchanger.class)),
|
||||
registeredBeans.stream()
|
||||
.map(RegisteredBean::getBeanClass)
|
||||
.filter(beanClass ->
|
||||
beanClass.isInterface() &&
|
||||
AnnotatedElementUtils.hasAnnotation(beanClass, MessagingGateway.class)));
|
||||
|
||||
return (generationContext, beanFactoryInitializationCode) -> {
|
||||
ProxyHints proxyHints = generationContext.getRuntimeHints().proxies();
|
||||
gatewayProxyInterfaces.forEach((gatewayInterface) ->
|
||||
|
||||
@@ -18,12 +18,17 @@ package org.springframework.integration.config;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.integration.gateway.AnnotationGatewayProxyFactoryBean;
|
||||
@@ -39,7 +44,7 @@ import org.springframework.integration.gateway.AnnotationGatewayProxyFactoryBean
|
||||
* @see AnnotationGatewayProxyFactoryBean
|
||||
*/
|
||||
class GatewayProxyInstantiationPostProcessor implements
|
||||
InstantiationAwareBeanPostProcessor, ApplicationContextAware {
|
||||
InstantiationAwareBeanPostProcessor, BeanRegistrationAotProcessor, ApplicationContextAware {
|
||||
|
||||
private final BeanDefinitionRegistry registry;
|
||||
|
||||
@@ -77,4 +82,17 @@ class GatewayProxyInstantiationPostProcessor implements
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
if (beanClass.isInterface() && AnnotatedElementUtils.hasAnnotation(beanClass, MessagingGateway.class)) {
|
||||
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
|
||||
beanDefinition.setBeanClass(AnnotationGatewayProxyFactoryBean.class);
|
||||
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanClass);
|
||||
beanDefinition.setTargetType(
|
||||
ResolvableType.forClassWithGenerics(AnnotationGatewayProxyFactoryBean.class, beanClass));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user