diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderAwareRouterBeanPostProcessor.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderAwareRouterBeanPostProcessor.java index 996ee7dc8..7433a3b74 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderAwareRouterBeanPostProcessor.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderAwareRouterBeanPostProcessor.java @@ -17,31 +17,26 @@ package org.springframework.cloud.stream.binder; import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.integration.router.AbstractMappingMessageRouter; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.core.DestinationResolver; /** * A {@link BeanPostProcessor} that sets a {@link BinderAwareChannelResolver} on any bean of type * {@link AbstractMappingMessageRouter} within the context. - * + * * @author Mark Fisher * @author Gary Russell */ -public class BinderAwareRouterBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { +public class BinderAwareRouterBeanPostProcessor implements BeanPostProcessor { - private final BinderAwareChannelResolver channelResolver; + private final DestinationResolver channelResolver; - public BinderAwareRouterBeanPostProcessor(BinderAwareChannelResolver channelResolver) { + public BinderAwareRouterBeanPostProcessor(DestinationResolver channelResolver) { this.channelResolver = channelResolver; } - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - channelResolver.setBeanFactory(beanFactory); - } - @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; @@ -50,7 +45,7 @@ public class BinderAwareRouterBeanPostProcessor implements BeanPostProcessor, Be @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof AbstractMappingMessageRouter) { - ((AbstractMappingMessageRouter) bean).setChannelResolver(channelResolver); + ((AbstractMappingMessageRouter) bean).setChannelResolver(this.channelResolver); } return bean; } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAdapterConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAdapterConfiguration.java index 3d8183f55..5accd1b4c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAdapterConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAdapterConfiguration.java @@ -38,6 +38,8 @@ import org.springframework.cloud.stream.endpoint.ChannelsEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.core.DestinationResolutionException; +import org.springframework.messaging.core.DestinationResolver; /** * Configuration class that provides necessary beans for {@link MessageChannel} binding. @@ -61,8 +63,9 @@ public class ChannelBindingAdapterConfiguration { @Bean public ChannelBindingAdapter bindingAdapter() { - ChannelBindingAdapter adapter = new ChannelBindingAdapter(this.module, this.binder); - adapter.setChannelLocator(new DefaultChannelLocator(module)); + ChannelBindingAdapter adapter = new ChannelBindingAdapter(this.module, + this.binder); + adapter.setChannelLocator(new DefaultChannelLocator(this.module)); adapter.setOutputChannels(getOutputChannels()); adapter.setInputChannels(getInputChannels()); adapter.setChannelResolver(binderAwareChannelResolver()); @@ -81,7 +84,8 @@ public class ChannelBindingAdapterConfiguration { BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition(name); // for now, just assume that the beans are at least AbstractBeanDefinition if (beanDefinition instanceof AbstractBeanDefinition - && ((AbstractBeanDefinition) beanDefinition).getQualifier(Output.class.getName()) != null) { + && ((AbstractBeanDefinition) beanDefinition) + .getQualifier(Output.class.getName()) != null) { channels.add(new OutputChannelBinding(name)); } } @@ -95,7 +99,8 @@ public class ChannelBindingAdapterConfiguration { BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition(name); // for now, just assume that the beans are at least AbstractBeanDefinition if (beanDefinition instanceof AbstractBeanDefinition - && ((AbstractBeanDefinition) beanDefinition).getQualifier(Input.class.getName()) != null) { + && ((AbstractBeanDefinition) beanDefinition).getQualifier(Input.class + .getName()) != null) { channels.add(new InputChannelBinding(name)); } } @@ -104,11 +109,35 @@ public class ChannelBindingAdapterConfiguration { @Bean public BinderAwareChannelResolver binderAwareChannelResolver() { - return new BinderAwareChannelResolver(BeanFactoryUtils.beanOfType(beanFactory, Binder.class), new Properties()); + return new BinderAwareChannelResolver(this.binder, new Properties()); } - @Bean - public BinderAwareRouterBeanPostProcessor binderAwareRouterBeanPostProcessor(BinderAwareChannelResolver resolver) { - return new BinderAwareRouterBeanPostProcessor(resolver); + // IMPORTANT: Nested class to avoid instantiating all of the above early + @Configuration + protected static class PostProcessorConfiguration { + + private BinderAwareChannelResolver binderAwareChannelResolver; + + @Bean + public BinderAwareRouterBeanPostProcessor binderAwareRouterBeanPostProcessor( + final ConfigurableListableBeanFactory beanFactory) { + // IMPORTANT: Lazy delegate to avoid instantiating all of the above early + return new BinderAwareRouterBeanPostProcessor( + new DestinationResolver() { + + @Override + public MessageChannel resolveDestination(String name) + throws DestinationResolutionException { + if (PostProcessorConfiguration.this.binderAwareChannelResolver == null) { + PostProcessorConfiguration.this.binderAwareChannelResolver = BeanFactoryUtils.beanOfType( + beanFactory, BinderAwareChannelResolver.class); + } + return PostProcessorConfiguration.this.binderAwareChannelResolver.resolveDestination(name); + } + + }); + } + } + }