diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aop/MessagePublishingInterceptor.java b/spring-integration-core/src/main/java/org/springframework/integration/aop/MessagePublishingInterceptor.java index 72a5dd20bc..1c61c845a6 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aop/MessagePublishingInterceptor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aop/MessagePublishingInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -70,10 +70,12 @@ public class MessagePublishingInterceptor implements MethodInterceptor, BeanFact private MessageBuilderFactory messageBuilderFactory = new DefaultMessageBuilderFactory(); - private boolean messageBuilderFactorySet; - private String defaultChannelName; + private volatile boolean messageBuilderFactorySet; + + private volatile boolean templateInitialized; + public MessagePublishingInterceptor(PublisherMetadataSource metadataSource) { Assert.notNull(metadataSource, "metadataSource must not be null"); this.metadataSource = metadataSource; @@ -94,10 +96,6 @@ public class MessagePublishingInterceptor implements MethodInterceptor, BeanFact @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; - this.messagingTemplate.setBeanFactory(beanFactory); - if (this.channelResolver == null) { - this.channelResolver = ChannelResolverUtils.getChannelResolver(this.beanFactory); - } } protected MessageBuilderFactory getMessageBuilderFactory() { @@ -111,8 +109,9 @@ public class MessagePublishingInterceptor implements MethodInterceptor, BeanFact } @Override - public final Object invoke(final MethodInvocation invocation) throws Throwable { - final StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory); + public final Object invoke(MethodInvocation invocation) throws Throwable { + initMessagingTemplateIfAny(); + StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory); Class targetClass = AopUtils.getTargetClass(invocation.getThis()); final Method method = AopUtils.getMostSpecificMethod(invocation.getMethod(), targetClass); String[] argumentNames = resolveArgumentNames(method); @@ -143,6 +142,16 @@ public class MessagePublishingInterceptor implements MethodInterceptor, BeanFact } } + private void initMessagingTemplateIfAny() { + if (!this.templateInitialized) { + this.messagingTemplate.setBeanFactory(this.beanFactory); + if (this.channelResolver == null) { + this.channelResolver = ChannelResolverUtils.getChannelResolver(this.beanFactory); + } + this.templateInitialized = true; + } + } + private String[] resolveArgumentNames(Method method) { return this.parameterNameDiscoverer.getParameterNames(method); } @@ -163,20 +172,14 @@ public class MessagePublishingInterceptor implements MethodInterceptor, BeanFact } Message message = builder.build(); String channelName = this.metadataSource.getChannelName(method); - MessageChannel channel = null; if (channelName != null) { - Assert.state(this.channelResolver != null, "ChannelResolver is required to resolve channel names."); - channel = this.channelResolver.resolveDestination(channelName); - } - if (channel != null) { - this.messagingTemplate.send(channel, message); + this.messagingTemplate.send(channelName, message); } else { String channelNameToUse = this.defaultChannelName; if (channelNameToUse != null && this.messagingTemplate.getDefaultDestination() == null) { Assert.state(this.channelResolver != null, "ChannelResolver is required to resolve channel names."); - this.messagingTemplate.setDefaultChannel( - this.channelResolver.resolveDestination(channelNameToUse)); + this.messagingTemplate.setDefaultChannel(this.channelResolver.resolveDestination(channelNameToUse)); this.defaultChannelName = null; } this.messagingTemplate.send(message); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfiguration.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfiguration.java index 807bb9876d..c0105f5612 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfiguration.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfiguration.java @@ -43,6 +43,7 @@ import org.springframework.util.Assert; * @since 4.2 */ @Configuration(proxyBeanMethods = false) +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class IntegrationManagementConfiguration implements ImportAware, EnvironmentAware { private AnnotationAttributes attributes; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/AbstractMethodAnnotationPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/AbstractMethodAnnotationPostProcessor.java index 0165c694f1..da916bc366 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/AbstractMethodAnnotationPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/AbstractMethodAnnotationPostProcessor.java @@ -125,25 +125,33 @@ public abstract class AbstractMethodAnnotationPostProcessor channelResolver; // NOSONAR - protected final Class annotationType; // NOSONAR + private volatile DestinationResolver channelResolver; + @SuppressWarnings(UNCHECKED) public AbstractMethodAnnotationPostProcessor(ConfigurableListableBeanFactory beanFactory) { Assert.notNull(beanFactory, "'beanFactory' must not be null"); this.messageHandlerAttributes.add(SEND_TIMEOUT_ATTRIBUTE); this.beanFactory = beanFactory; this.definitionRegistry = (BeanDefinitionRegistry) beanFactory; - this.conversionService = this.beanFactory.getConversionService() != null - ? this.beanFactory.getConversionService() - : DefaultConversionService.getSharedInstance(); - this.channelResolver = ChannelResolverUtils.getChannelResolver(beanFactory); + this.conversionService = + this.beanFactory.getConversionService() != null + ? this.beanFactory.getConversionService() + : DefaultConversionService.getSharedInstance(); this.annotationType = (Class) GenericTypeResolver.resolveTypeArgument(this.getClass(), MethodAnnotationPostProcessor.class); } + + protected DestinationResolver getChannelResolver() { + if (this.channelResolver == null) { + this.channelResolver = ChannelResolverUtils.getChannelResolver(this.beanFactory); + } + return this.channelResolver; + } + @Override public Object postProcess(Object bean, String beanName, Method method, List annotations) { Object sourceHandler = null; @@ -332,7 +340,7 @@ public abstract class AbstractMethodAnnotationPostProcessor