Skip to content

Commit 47a4b28

Browse files
artembilangaryrussell
authored andcommitted
INT-4556: Fix messaging anns for FactoryBeans
JIRA: https://jira.spring.io/browse/INT-4556 We definitely need to resolve a `@Bean` method to the target object to be sure do not create a new `MessageHandler` bean. **Cherry-pick to 5.0.x**
1 parent d1b3046 commit 47a4b28

File tree

5 files changed

+44
-31
lines changed

5 files changed

+44
-31
lines changed

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,13 @@ public AbstractMethodAnnotationPostProcessor(ConfigurableListableBeanFactory bea
128128

129129
@Override
130130
public Object postProcess(Object bean, String beanName, Method method, List<Annotation> annotations) {
131-
if (this.beanAnnotationAware() && AnnotatedElementUtils.isAnnotated(method, Bean.class.getName())) {
131+
Object sourceHandler = null;
132+
if (beanAnnotationAware() && AnnotatedElementUtils.isAnnotated(method, Bean.class.getName())) {
132133
if (!this.beanFactory.containsBeanDefinition(resolveTargetBeanName(method))) {
133134
this.logger.debug("Skipping endpoint creation; perhaps due to some '@Conditional' annotation.");
134135
return null;
135136
}
136-
}
137-
138-
Object sourceHandler = null;
139-
if (beanAnnotationAware() && AnnotatedElementUtils.isAnnotated(method, Bean.class.getName())) {
140-
if (MessageHandler.class.isAssignableFrom(method.getReturnType())) {
137+
else {
141138
sourceHandler = resolveTargetBeanFromMethodWithBeanAnnotation(method);
142139
}
143140
}
@@ -159,12 +156,15 @@ public Object postProcess(Object bean, String beanName, Method method, List<Anno
159156
if (handler instanceof AbstractMessageProducingHandler || handler instanceof AbstractMessageRouter) {
160157
String sendTimeout = MessagingAnnotationUtils.resolveAttribute(annotations, "sendTimeout", String.class);
161158
if (sendTimeout != null) {
162-
Long value = Long.valueOf(this.beanFactory.resolveEmbeddedValue(sendTimeout));
163-
if (handler instanceof AbstractMessageProducingHandler) {
164-
((AbstractMessageProducingHandler) handler).setSendTimeout(value);
165-
}
166-
else {
167-
((AbstractMessageRouter) handler).setSendTimeout(value);
159+
String resolvedValue = this.beanFactory.resolveEmbeddedValue(sendTimeout);
160+
if (resolvedValue != null) {
161+
long value = Long.parseLong(resolvedValue);
162+
if (handler instanceof AbstractMessageProducingHandler) {
163+
((AbstractMessageProducingHandler) handler).setSendTimeout(value);
164+
}
165+
else {
166+
((AbstractMessageRouter) handler).setSendTimeout(value);
167+
}
168168
}
169169
}
170170
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2015 the original author or authors.
2+
* Copyright 2014-2018 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.
@@ -37,6 +37,7 @@
3737
* Post-processor for the {@link BridgeFrom @BridgeFrom} annotation.
3838
*
3939
* @author Artem Bilan
40+
*
4041
* @since 4.0
4142
*/
4243
public class BridgeFromAnnotationPostProcessor extends AbstractMethodAnnotationPostProcessor<BridgeFrom> {
@@ -78,4 +79,9 @@ protected MessageHandler createHandler(Object bean, Method method, List<Annotati
7879
return handler;
7980
}
8081

82+
@Override
83+
protected Object resolveTargetBeanFromMethodWithBeanAnnotation(Method method) {
84+
return null;
85+
}
86+
8187
}

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,11 @@ public class MessagingAnnotationPostProcessor implements BeanPostProcessor, Bean
7272

7373
protected final Log logger = LogFactory.getLog(this.getClass()); // NOSONAR
7474

75-
private final Map<Class<? extends Annotation>, MethodAnnotationPostProcessor<?>> postProcessors =
76-
new HashMap<Class<? extends Annotation>, MethodAnnotationPostProcessor<?>>();
75+
private final Map<Class<? extends Annotation>, MethodAnnotationPostProcessor<?>> postProcessors = new HashMap<>();
7776

7877
private ConfigurableListableBeanFactory beanFactory;
7978

80-
private final Set<Class<?>> noAnnotationsCache =
81-
Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>(256));
79+
private final Set<Class<?>> noAnnotationsCache = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
8280

8381
@Override
8482
public void setBeanFactory(BeanFactory beanFactory) {
@@ -222,13 +220,15 @@ protected void processAnnotationTypeOnMethod(Object bean, String beanName, Metho
222220
*/
223221
protected List<Annotation> getAnnotationChain(Method method, Class<? extends Annotation> annotationType) {
224222
Annotation[] annotations = AnnotationUtils.getAnnotations(method);
225-
List<Annotation> annotationChain = new LinkedList<Annotation>();
226-
Set<Annotation> visited = new HashSet<Annotation>();
227-
for (Annotation ann : annotations) {
228-
recursiveFindAnnotation(annotationType, ann, annotationChain, visited);
229-
if (annotationChain.size() > 0) {
230-
Collections.reverse(annotationChain);
231-
return annotationChain;
223+
List<Annotation> annotationChain = new LinkedList<>();
224+
if (annotations != null) {
225+
Set<Annotation> visited = new HashSet<>();
226+
for (Annotation ann : annotations) {
227+
recursiveFindAnnotation(annotationType, ann, annotationChain, visited);
228+
if (annotationChain.size() > 0) {
229+
Collections.reverse(annotationChain);
230+
return annotationChain;
231+
}
232232
}
233233
}
234234
return annotationChain;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public ServiceActivatorAnnotationPostProcessor(ConfigurableListableBeanFactory b
5252
protected MessageHandler createHandler(Object bean, Method method, List<Annotation> annotations) {
5353
AbstractReplyProducingMessageHandler serviceActivator;
5454
if (AnnotatedElementUtils.isAnnotated(method, Bean.class.getName())) {
55-
final Object target = this.resolveTargetBeanFromMethodWithBeanAnnotation(method);
56-
serviceActivator = this.extractTypeIfPossible(target, AbstractReplyProducingMessageHandler.class);
55+
final Object target = resolveTargetBeanFromMethodWithBeanAnnotation(method);
56+
serviceActivator = extractTypeIfPossible(target, AbstractReplyProducingMessageHandler.class);
5757
if (serviceActivator == null) {
5858
if (target instanceof MessageHandler) {
5959
/*

spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
import org.springframework.integration.endpoint.PollingConsumer;
112112
import org.springframework.integration.expression.SpelPropertyAccessorRegistrar;
113113
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
114+
import org.springframework.integration.handler.ServiceActivatingHandler;
114115
import org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice;
115116
import org.springframework.integration.history.MessageHistory;
116117
import org.springframework.integration.history.MessageHistoryConfigurer;
@@ -421,11 +422,17 @@ public void testAnnotatedServiceActivator() throws Exception {
421422
assertEquals("FOO", message.getHeaders().get("foo"));
422423

423424
MessagingTemplate messagingTemplate = new MessagingTemplate(this.controlBusChannel);
424-
assertFalse(messagingTemplate.convertSendAndReceive("@lifecycle.isRunning()", Boolean.class));
425-
this.controlBusChannel.send(new GenericMessage<String>("@lifecycle.start()"));
426-
assertTrue(messagingTemplate.convertSendAndReceive("@lifecycle.isRunning()", Boolean.class));
427-
this.controlBusChannel.send(new GenericMessage<String>("@lifecycle.stop()"));
428-
assertFalse(messagingTemplate.convertSendAndReceive("@lifecycle.isRunning()", Boolean.class));
425+
assertEquals(false, messagingTemplate.convertSendAndReceive("@lifecycle.isRunning()", Boolean.class));
426+
this.controlBusChannel.send(new GenericMessage<>("@lifecycle.start()"));
427+
assertEquals(true, messagingTemplate.convertSendAndReceive("@lifecycle.isRunning()", Boolean.class));
428+
this.controlBusChannel.send(new GenericMessage<>("@lifecycle.stop()"));
429+
assertEquals(false, messagingTemplate.convertSendAndReceive("@lifecycle.isRunning()", Boolean.class));
430+
431+
Map<String, ServiceActivatingHandler> beansOfType =
432+
this.context.getBeansOfType(ServiceActivatingHandler.class);
433+
434+
assertFalse(beansOfType.keySet()
435+
.contains("enableIntegrationTests.ContextConfiguration2.controlBus.serviceActivator.handler"));
429436
}
430437

431438
@Test

0 commit comments

Comments
 (0)