Skip to content

Commit 921864c

Browse files
committed
spring-projectsGH-3945: Fix not eligible for getting processed
Fixes spring-projects#3945 The `IntegrationManagementConfiguration` produces an `IntegrationManagementConfigurer` which is a `BeanPostProcessor`. According to Spring recommendation this kind of infrastructure beans must be declared as `static`. Due to an `implements ImportAware, EnvironmentAware` nature of the `IntegrationManagementConfiguration`, we cannot use `static @Bean` method. But since the `IntegrationManagementConfiguration` is not involved in any bean post-processing, it is safe to follow recommendation and mark it as a `@Role(BeanDefinition.ROLE_INFRASTRUCTURE)`. * Fix `MessagePublishingInterceptor` to initialize `MessagingTemplate` and `DestinationResolver` lazily * Fix `AbstractMethodAnnotationPostProcessor` to initialize `DestinationResolver` lazily **Cherry-pick to `5.5.x`**
1 parent e19e6d4 commit 921864c

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

spring-integration-core/src/main/java/org/springframework/integration/aop/MessagePublishingInterceptor.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
1919
import java.lang.reflect.Method;
2020
import java.util.HashMap;
2121
import java.util.Map;
22+
import java.util.concurrent.atomic.AtomicBoolean;
2223

2324
import org.aopalliance.intercept.MethodInterceptor;
2425
import org.aopalliance.intercept.MethodInvocation;
@@ -64,6 +65,8 @@ public class MessagePublishingInterceptor implements MethodInterceptor, BeanFact
6465

6566
private final PublisherMetadataSource metadataSource;
6667

68+
private final AtomicBoolean templateInitialized = new AtomicBoolean();
69+
6770
private DestinationResolver<MessageChannel> channelResolver;
6871

6972
private BeanFactory beanFactory;
@@ -94,10 +97,6 @@ public void setChannelResolver(DestinationResolver<MessageChannel> channelResolv
9497
@Override
9598
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
9699
this.beanFactory = beanFactory;
97-
this.messagingTemplate.setBeanFactory(beanFactory);
98-
if (this.channelResolver == null) {
99-
this.channelResolver = ChannelResolverUtils.getChannelResolver(this.beanFactory);
100-
}
101100
}
102101

103102
protected MessageBuilderFactory getMessageBuilderFactory() {
@@ -111,8 +110,9 @@ protected MessageBuilderFactory getMessageBuilderFactory() {
111110
}
112111

113112
@Override
114-
public final Object invoke(final MethodInvocation invocation) throws Throwable {
115-
final StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
113+
public final Object invoke(MethodInvocation invocation) throws Throwable {
114+
initMessagingTemplateIfAny();
115+
StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
116116
Class<?> targetClass = AopUtils.getTargetClass(invocation.getThis());
117117
final Method method = AopUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
118118
String[] argumentNames = resolveArgumentNames(method);
@@ -143,6 +143,15 @@ public final Object invoke(final MethodInvocation invocation) throws Throwable {
143143
}
144144
}
145145

146+
private void initMessagingTemplateIfAny() {
147+
if (this.templateInitialized.compareAndSet(false, true)) {
148+
this.messagingTemplate.setBeanFactory(beanFactory);
149+
if (this.channelResolver == null) {
150+
this.channelResolver = ChannelResolverUtils.getChannelResolver(this.beanFactory);
151+
}
152+
}
153+
}
154+
146155
private String[] resolveArgumentNames(Method method) {
147156
return this.parameterNameDiscoverer.getParameterNames(method);
148157
}
@@ -163,20 +172,14 @@ private void publishMessage(Method method, StandardEvaluationContext context) {
163172
}
164173
Message<?> message = builder.build();
165174
String channelName = this.metadataSource.getChannelName(method);
166-
MessageChannel channel = null;
167175
if (channelName != null) {
168-
Assert.state(this.channelResolver != null, "ChannelResolver is required to resolve channel names.");
169-
channel = this.channelResolver.resolveDestination(channelName);
170-
}
171-
if (channel != null) {
172-
this.messagingTemplate.send(channel, message);
176+
this.messagingTemplate.send(channelName, message);
173177
}
174178
else {
175179
String channelNameToUse = this.defaultChannelName;
176180
if (channelNameToUse != null && this.messagingTemplate.getDefaultDestination() == null) {
177181
Assert.state(this.channelResolver != null, "ChannelResolver is required to resolve channel names.");
178-
this.messagingTemplate.setDefaultChannel(
179-
this.channelResolver.resolveDestination(channelNameToUse));
182+
this.messagingTemplate.setDefaultChannel(this.channelResolver.resolveDestination(channelNameToUse));
180183
this.defaultChannelName = null;
181184
}
182185
this.messagingTemplate.send(message);

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public abstract class AbstractMethodAnnotationPostProcessor<T extends Annotation
141141

142142
private ConversionService conversionService;
143143

144-
private DestinationResolver<MessageChannel> channelResolver;
144+
private volatile DestinationResolver<MessageChannel> channelResolver;
145145

146146
@SuppressWarnings(UNCHECKED)
147147
public AbstractMethodAnnotationPostProcessor() {
@@ -154,10 +154,10 @@ public AbstractMethodAnnotationPostProcessor() {
154154
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
155155
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
156156
this.definitionRegistry = (BeanDefinitionRegistry) beanFactory;
157-
this.conversionService = this.beanFactory.getConversionService() != null
158-
? this.beanFactory.getConversionService()
159-
: DefaultConversionService.getSharedInstance();
160-
this.channelResolver = ChannelResolverUtils.getChannelResolver(beanFactory);
157+
this.conversionService =
158+
this.beanFactory.getConversionService() != null
159+
? this.beanFactory.getConversionService()
160+
: DefaultConversionService.getSharedInstance();
161161
}
162162

163163
protected ConfigurableListableBeanFactory getBeanFactory() {
@@ -173,6 +173,9 @@ protected ConversionService getConversionService() {
173173
}
174174

175175
protected DestinationResolver<MessageChannel> getChannelResolver() {
176+
if (this.channelResolver == null) {
177+
this.channelResolver = ChannelResolverUtils.getChannelResolver(beanFactory);
178+
}
176179
return this.channelResolver;
177180
}
178181

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@
4444
*
4545
* @author Artem Bilan
4646
* @author Gary Russell
47+
*
4748
* @since 4.2
4849
*/
4950
@Configuration(proxyBeanMethods = false)
51+
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
5052
public class IntegrationManagementConfiguration implements ImportAware, EnvironmentAware {
5153

5254
private AnnotationAttributes attributes;

0 commit comments

Comments
 (0)