INT-4487: Allow reconfiguring ARPMH.adviceChain
JIRA: https://jira.spring.io/browse/INT-4487 Currently the `AbstractReplyProducingMessageHandler` applies advices only in the `afterPropertiesSet()` phase. When we use bean references for `MessageHandler`s in Java DSL, the `.advice()` provided in the flow definition is not applied to the `AbstractReplyProducingMessageHandler`. * For consistency with the endpoint configured by the DSL definition, override and reconfigure advices in the `AbstractReplyProducingMessageHandler` bean reference during DSL parsing and processing. Fix `TwitterSearchOutboundGatewayParserTests` for the proper assert
This commit is contained in:
committed by
Gary Russell
parent
0735ddb0ed
commit
e6a35c4a60
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -75,26 +75,28 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
|
||||
|
||||
private final ConversionService defaultConversionService = DefaultConversionService.getSharedInstance();
|
||||
|
||||
private volatile DestinationResolver<MessageChannel> channelResolver;
|
||||
private DestinationResolver<MessageChannel> channelResolver;
|
||||
|
||||
private volatile String beanName;
|
||||
private String beanName;
|
||||
|
||||
private volatile String componentName;
|
||||
private String componentName;
|
||||
|
||||
private volatile BeanFactory beanFactory;
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private volatile TaskScheduler taskScheduler;
|
||||
private TaskScheduler taskScheduler;
|
||||
|
||||
private volatile Properties integrationProperties = IntegrationProperties.defaults();
|
||||
private Properties integrationProperties = IntegrationProperties.defaults();
|
||||
|
||||
private volatile ConversionService conversionService;
|
||||
private ConversionService conversionService;
|
||||
|
||||
private volatile ApplicationContext applicationContext;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private volatile MessageBuilderFactory messageBuilderFactory;
|
||||
private MessageBuilderFactory messageBuilderFactory;
|
||||
|
||||
private Expression expression;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
@Override
|
||||
public final void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
@@ -181,6 +183,8 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
|
||||
}
|
||||
throw new BeanInitializationException("failed to initialize", e);
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,6 +194,14 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
|
||||
protected void onInit() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the status of this component if it has been initialized already.
|
||||
* @return the flag if this component has been initialized already.
|
||||
*/
|
||||
protected boolean isInitialized() {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
protected BeanFactory getBeanFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
* Copyright 2016-2018 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.
|
||||
@@ -96,7 +96,9 @@ public class BarrierSpec extends ConsumerEndpointSpec<BarrierSpec, BarrierMessag
|
||||
@Override
|
||||
public Tuple2<ConsumerEndpointFactoryBean, BarrierMessageHandler> doGet() {
|
||||
this.handler = new BarrierMessageHandler(this.timeout, this.outputProcessor, this.correlationStrategy);
|
||||
this.handler.setAdviceChain(this.adviceChain);
|
||||
if (!this.adviceChain.isEmpty()) {
|
||||
this.handler.setAdviceChain(this.adviceChain);
|
||||
}
|
||||
this.handler.setRequiresReply(this.requiresReply);
|
||||
this.handler.setSendTimeout(this.sendTimeout);
|
||||
this.handler.setAsync(this.async);
|
||||
|
||||
@@ -267,7 +267,7 @@ public abstract class ConsumerEndpointSpec<S extends ConsumerEndpointSpec<S, H>,
|
||||
@Override
|
||||
protected Tuple2<ConsumerEndpointFactoryBean, H> doGet() {
|
||||
this.endpointFactoryBean.setAdviceChain(this.adviceChain);
|
||||
if (this.handler instanceof AbstractReplyProducingMessageHandler) {
|
||||
if (this.handler instanceof AbstractReplyProducingMessageHandler && !this.adviceChain.isEmpty()) {
|
||||
((AbstractReplyProducingMessageHandler) this.handler).setAdviceChain(this.adviceChain);
|
||||
}
|
||||
this.endpointFactoryBean.setHandler(this.handler);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.integration.handler;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
@@ -26,7 +27,6 @@ import org.springframework.integration.handler.advice.HandleMessageAdvice;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Base class for MessageHandlers that are capable of producing replies.
|
||||
@@ -41,14 +41,14 @@ import org.springframework.util.CollectionUtils;
|
||||
public abstract class AbstractReplyProducingMessageHandler extends AbstractMessageProducingHandler
|
||||
implements BeanClassLoaderAware {
|
||||
|
||||
private final List<Advice> adviceChain = new LinkedList<>();
|
||||
|
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private boolean requiresReply = false;
|
||||
|
||||
private volatile RequestHandler advisedRequestHandler;
|
||||
|
||||
private volatile List<Advice> adviceChain;
|
||||
|
||||
private volatile ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private volatile boolean requiresReply = false;
|
||||
|
||||
/**
|
||||
* Flag whether a reply is required. If true an incoming message MUST result in a reply message being sent.
|
||||
* If false an incoming message MAY result in a reply message being sent. Default is false.
|
||||
@@ -62,13 +62,23 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
return this.requiresReply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a list of {@link Advice}s to proxy a {@link #handleRequestMessage(Message)} method.
|
||||
* @param adviceChain the list of {@link Advice}s to use.
|
||||
*/
|
||||
public void setAdviceChain(List<Advice> adviceChain) {
|
||||
Assert.notNull(adviceChain, "adviceChain cannot be null");
|
||||
this.adviceChain = adviceChain;
|
||||
Assert.notEmpty(adviceChain, "adviceChain cannot be empty");
|
||||
synchronized (this.adviceChain) {
|
||||
this.adviceChain.clear();
|
||||
this.adviceChain.addAll(adviceChain);
|
||||
if (isInitialized()) {
|
||||
initAdvisedRequestHandlerIfAny();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasAdviceChain() {
|
||||
return this.adviceChain != null && this.adviceChain.size() > 0;
|
||||
return this.adviceChain.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,7 +90,12 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
@Override
|
||||
protected final void onInit() throws Exception {
|
||||
super.onInit();
|
||||
if (!CollectionUtils.isEmpty(this.adviceChain)) {
|
||||
initAdvisedRequestHandlerIfAny();
|
||||
doInit();
|
||||
}
|
||||
|
||||
private void initAdvisedRequestHandlerIfAny() {
|
||||
if (!this.adviceChain.isEmpty()) {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(new AdvisedRequestHandler());
|
||||
boolean advised = false;
|
||||
for (Advice advice : this.adviceChain) {
|
||||
@@ -93,7 +108,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
this.advisedRequestHandler = (RequestHandler) proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
}
|
||||
doInit();
|
||||
}
|
||||
|
||||
protected void doInit() {
|
||||
@@ -154,9 +168,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
|
||||
Object handleRequestMessage(Message<?> requestMessage);
|
||||
|
||||
@Override
|
||||
String toString();
|
||||
|
||||
/**
|
||||
* Utility method, intended for use in message handler advice classes to get
|
||||
* information about the advised object. For example:
|
||||
|
||||
Reference in New Issue
Block a user