diff --git a/docs/src/reference/docbook/router.xml b/docs/src/reference/docbook/router.xml
index 5f5d896d4b..e4bfe6b2d4 100644
--- a/docs/src/reference/docbook/router.xml
+++ b/docs/src/reference/docbook/router.xml
@@ -96,10 +96,6 @@
order
-
- channel-resolver
-
- method
@@ -188,10 +184,6 @@
order
-
- channel-resolver
-
- method
@@ -793,8 +785,8 @@ public List route(@Header("orderStatus") OrderStatus status)]]>
Step 3 - Resolve channel name to the actual instance of the
- MessageChannel where using ChannelResolver, the router will obtain a
- reference to a bean (which is hopefully a MessageChannel) identified by the result of the
+ MessageChannel as a reference to a bean within the Application Context
+ (which is hopefully a MessageChannel) identified by the result of the
previous step.
@@ -825,8 +817,8 @@ public List route(@Header("orderStatus") OrderStatus status)]]>
Step 3 - Resolve channel name to the actual instance of the
- MessageChannel where using ChannelResolver, the router will obtain a
- reference to a bean (which is hopefully a MessageChannel) identified by the result of the
+ MessageChannel as a reference to a bean within the Application Context
+ (which is hopefully a MessageChannel) identified by the result of the
previous step.
@@ -860,9 +852,8 @@ public List route(@Header("orderStatus") OrderStatus status)]]>
So all that is left is for Step 3 to resolve the channel name ('kermit') to an actual instance of the
- MessageChannel identified by this name. That will be done via the default
- ChannelResolver implementation which is a BeanFactoryChannelResolver. It
- basically does a bean lookup for the name provided. So now all messages which contain the header/value pair as testHeader=kermit
+ MessageChannel identified by this name. That basically involves a bean lookup
+ for the name provided. So now all messages which contain the header/value pair as testHeader=kermit
are going to be routed to a MessageChannel whose bean name (id) is 'kermit'.
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java
index 4580252a1a..99c2abfaae 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/RouterFactoryBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2011 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. You may obtain a copy of the License at
@@ -18,10 +18,9 @@ import java.util.Map;
import org.springframework.expression.Expression;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.MessageHandler;
-import org.springframework.integration.router.AbstractMessageRouter;
+import org.springframework.integration.router.AbstractMappingMessageRouter;
import org.springframework.integration.router.ExpressionEvaluatingRouter;
import org.springframework.integration.router.MethodInvokingRouter;
-import org.springframework.integration.support.channel.ChannelResolver;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -35,9 +34,7 @@ import org.springframework.util.StringUtils;
*/
public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean {
- private volatile ChannelResolver channelResolver;
-
- private volatile Map channelIdentifierMap;
+ private volatile Map channelMappings;
private volatile MessageChannel defaultOutputChannel;
@@ -50,10 +47,6 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean
private volatile Boolean ignoreSendFailures;
- public void setChannelResolver(ChannelResolver channelResolver) {
- this.channelResolver = channelResolver;
- }
-
public void setDefaultOutputChannel(MessageChannel defaultOutputChannel) {
this.defaultOutputChannel = defaultOutputChannel;
}
@@ -74,14 +67,14 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean
this.ignoreSendFailures = ignoreSendFailures;
}
- public void setChannelIdentifierMap(Map channelIdentifierMap) {
- this.channelIdentifierMap = channelIdentifierMap;
+ public void setChannelMappings(Map channelMappings) {
+ this.channelMappings = channelMappings;
}
@Override
MessageHandler createMethodInvokingHandler(Object targetObject, String targetMethodName) {
Assert.notNull(targetObject, "target object must not be null");
- AbstractMessageRouter router = this.extractTypeIfPossible(targetObject, AbstractMessageRouter.class);
+ AbstractMappingMessageRouter router = this.extractTypeIfPossible(targetObject, AbstractMappingMessageRouter.class);
if (router == null) {
router = this.createMethodInvokingRouter(targetObject, targetMethodName);
this.configureRouter(router);
@@ -102,19 +95,16 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean
return this.configureRouter(new ExpressionEvaluatingRouter(expression));
}
- private AbstractMessageRouter createMethodInvokingRouter(Object targetObject, String targetMethodName) {
+ private AbstractMappingMessageRouter createMethodInvokingRouter(Object targetObject, String targetMethodName) {
MethodInvokingRouter router = (StringUtils.hasText(targetMethodName))
? new MethodInvokingRouter(targetObject, targetMethodName)
: new MethodInvokingRouter(targetObject);
return router;
}
- private AbstractMessageRouter configureRouter(AbstractMessageRouter router) {
- if (this.channelResolver != null) {
- router.setChannelResolver(this.channelResolver);
- }
- if (this.channelIdentifierMap != null) {
- router.setChannelIdentifierMap(this.channelIdentifierMap);
+ private AbstractMappingMessageRouter configureRouter(AbstractMappingMessageRouter router) {
+ if (this.channelMappings != null) {
+ router.setChannelMappings(this.channelMappings);
}
if (this.defaultOutputChannel != null) {
router.setDefaultOutputChannel(this.defaultOutputChannel);
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java
index 10292e524b..afbc6f1cd4 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/annotation/RouterAnnotationPostProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2011 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.
@@ -41,7 +41,7 @@ public class RouterAnnotationPostProcessor extends AbstractMethodAnnotationPostP
@Override
protected MessageHandler createHandler(Object bean, Method method, Router annotation) {
MethodInvokingRouter router = new MethodInvokingRouter(bean, method);
- router.setChannelResolver(this.channelResolver);
+ router.setBeanFactory(this.beanFactory);
String defaultOutputChannelName = annotation.defaultOutputChannel();
if (StringUtils.hasText(defaultOutputChannelName)) {
MessageChannel defaultOutputChannel = this.channelResolver.resolveChannelName(defaultOutputChannelName);
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java
index d71772d157..2923617092 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractRouterParser.java
@@ -21,11 +21,11 @@ import java.util.List;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
+import org.springframework.integration.config.RouterFactoryBean;
+import org.springframework.util.CollectionUtils;
import org.springframework.util.xml.DomUtils;
/**
@@ -37,8 +37,7 @@ public abstract class AbstractRouterParser extends AbstractConsumerEndpointParse
@Override
protected final BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
- IntegrationNamespaceUtils.BASE_PACKAGE + ".config.RouterFactoryBean");
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RouterFactoryBean.class);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "default-output-channel");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "timeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "resolution-required");
@@ -52,28 +51,28 @@ public abstract class AbstractRouterParser extends AbstractConsumerEndpointParse
protected final BeanDefinition parseRouter(Element element, ParserContext parserContext) {
BeanDefinition beanDefinition = this.doParseRouter(element, parserContext);
if (beanDefinition != null) {
- String channelResolver = element.getAttribute("channel-resolver");
- if (StringUtils.hasText(channelResolver)){
- beanDefinition.getPropertyValues().add("channelResolver", new RuntimeBeanReference(channelResolver));
- }
// check if mapping is provided otherwise returned values will be treated as channel names
- List childElements = DomUtils.getChildElementsByTagName(element, "mapping");
- if (childElements != null && childElements.size() > 0) {
- ManagedMap channelMap = new ManagedMap();
- for (Element childElement : childElements) {
- String key = childElement.getAttribute(this.getMappingKeyAttributeValue());
- channelMap.put(key, childElement.getAttribute("channel"));
+ List mappingElements = DomUtils.getChildElementsByTagName(element, "mapping");
+ if (!CollectionUtils.isEmpty(mappingElements)) {
+ ManagedMap channelMappings = new ManagedMap();
+ for (Element mappingElement : mappingElements) {
+ String key = mappingElement.getAttribute(this.getMappingKeyAttributeName());
+ channelMappings.put(key, mappingElement.getAttribute("channel"));
}
- beanDefinition.getPropertyValues().add("channelIdentifierMap", channelMap);
+ beanDefinition.getPropertyValues().add("channelMappings", channelMappings);
}
}
return beanDefinition;
}
- protected abstract BeanDefinition doParseRouter(Element element, ParserContext parserContext);
-
- protected String getMappingKeyAttributeValue(){
+ /**
+ * Returns the name of the attribute that provides a key for the
+ * channel mappings. This can be overridden by subclasses.
+ */
+ protected String getMappingKeyAttributeName() {
return "value";
}
+ protected abstract BeanDefinition doParseRouter(Element element, ParserContext parserContext);
+
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java
index 6d41dba418..d434544a6b 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/DefaultRouterParser.java
@@ -18,14 +18,13 @@ package org.springframework.integration.config.xml;
import java.util.List;
+import org.w3c.dom.Element;
+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
/**
* Parser for the <router/> element.
@@ -35,9 +34,6 @@ import org.w3c.dom.Element;
*/
public class DefaultRouterParser extends AbstractDelegatingConsumerEndpointParser {
- private static final String CHANNEL_RESOLVER_PROPERTY = "channelResolver";
-
-
@Override
String getFactoryBeanClassName() {
return IntegrationNamespaceUtils.BASE_PACKAGE + ".config.RouterFactoryBean";
@@ -50,30 +46,13 @@ public class DefaultRouterParser extends AbstractDelegatingConsumerEndpointParse
@Override
protected void postProcess(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
- String resolverBeanName = element.getAttribute("channel-resolver");
List mappingElements = DomUtils.getChildElementsByTagName(element, "mapping");
if (!CollectionUtils.isEmpty(mappingElements)) {
- if (StringUtils.hasText(resolverBeanName)) {
- parserContext.getReaderContext().error(
- "The 'channel-resolver' attribute and 'mapping' sub-elements are mutually exclusive.",
- parserContext.extractSource(element));
- }
- BeanDefinitionBuilder channelResolverBuilder = BeanDefinitionBuilder.genericBeanDefinition(
- IntegrationNamespaceUtils.BASE_PACKAGE + ".support.channel.BeanFactoryChannelResolver");
- ManagedMap channelMap = new ManagedMap();
+ ManagedMap channelMappings = new ManagedMap();
for (Element mappingElement : mappingElements) {
- channelMap.put(mappingElement.getAttribute("value"), mappingElement.getAttribute("channel"));
+ channelMappings.put(mappingElement.getAttribute("value"), mappingElement.getAttribute("channel"));
}
- builder.addPropertyValue("channelIdentifierMap", channelMap);
- builder.addPropertyValue(CHANNEL_RESOLVER_PROPERTY, channelResolverBuilder.getBeanDefinition());
- }
- else if (StringUtils.hasText(resolverBeanName)) {
- builder.addPropertyReference(CHANNEL_RESOLVER_PROPERTY, resolverBeanName);
- }
- else {
- RootBeanDefinition resolverBeanDefintion = new RootBeanDefinition(
- IntegrationNamespaceUtils.BASE_PACKAGE + ".support.channel.BeanFactoryChannelResolver");
- builder.addPropertyValue(CHANNEL_RESOLVER_PROPERTY, resolverBeanDefintion);
+ builder.addPropertyValue("channelMappings", channelMappings);
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "default-output-channel");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "timeout");
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java
index 6086db8033..d431f55812 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/ErrorMessageExceptionTypeRouterParser.java
@@ -16,11 +16,13 @@
package org.springframework.integration.config.xml;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.router.ErrorMessageExceptionTypeRouter;
+
/**
* Parser for the <exception-type-router/> element.
*
@@ -28,17 +30,15 @@ import org.w3c.dom.Element;
* @since 2.0.4
*/
public class ErrorMessageExceptionTypeRouterParser extends AbstractRouterParser {
-
+
@Override
- protected BeanDefinition doParseRouter(Element element,
- ParserContext parserContext) {
- BeanDefinitionBuilder payloadTypeRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
- IntegrationNamespaceUtils.BASE_PACKAGE + ".router.ErrorMessageExceptionTypeRouter");
- return payloadTypeRouterBuilder.getBeanDefinition();
- }
-
- @Override
- protected String getMappingKeyAttributeValue(){
+ protected String getMappingKeyAttributeName() {
return "exception-type";
}
+
+ @Override
+ protected BeanDefinition doParseRouter(Element element, ParserContext parserContext) {
+ return new RootBeanDefinition(ErrorMessageExceptionTypeRouter.class);
+ }
+
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java
index 704489c496..ae4cfcc045 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/HeaderValueRouterParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2011 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.
@@ -21,6 +21,7 @@ import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.router.HeaderValueRouter;
/**
* Parser for the <header-value-router/> element.
@@ -33,8 +34,7 @@ public class HeaderValueRouterParser extends AbstractRouterParser {
@Override
protected BeanDefinition doParseRouter(Element element, ParserContext parserContext) {
- BeanDefinitionBuilder headerValueRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
- IntegrationNamespaceUtils.BASE_PACKAGE + ".router.HeaderValueRouter");
+ BeanDefinitionBuilder headerValueRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition(HeaderValueRouter.class);
headerValueRouterBuilder.addConstructorArgValue(element.getAttribute("header-name"));
return headerValueRouterBuilder.getBeanDefinition();
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java
index 3c3f565014..15d79ba7d9 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadTypeRouterParser.java
@@ -17,8 +17,9 @@
package org.springframework.integration.config.xml;
import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.router.PayloadTypeRouter;
import org.w3c.dom.Element;
/**
@@ -29,17 +30,15 @@ import org.w3c.dom.Element;
* @since 1.0.3
*/
public class PayloadTypeRouterParser extends AbstractRouterParser {
-
+
@Override
- protected BeanDefinition doParseRouter(Element element,
- ParserContext parserContext) {
- BeanDefinitionBuilder payloadTypeRouterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
- IntegrationNamespaceUtils.BASE_PACKAGE + ".router.PayloadTypeRouter");
- return payloadTypeRouterBuilder.getBeanDefinition();
- }
-
- @Override
- protected String getMappingKeyAttributeValue(){
+ protected String getMappingKeyAttributeName() {
return "type";
}
+
+ @Override
+ protected BeanDefinition doParseRouter(Element element, ParserContext parserContext) {
+ return new RootBeanDefinition(PayloadTypeRouter.class);
+ }
+
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java
new file mode 100644
index 0000000000..69229406fa
--- /dev/null
+++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2002-2011 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.integration.router;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.integration.Message;
+import org.springframework.integration.MessageChannel;
+import org.springframework.integration.MessagingException;
+import org.springframework.integration.support.channel.BeanFactoryChannelResolver;
+import org.springframework.integration.support.channel.ChannelResolutionException;
+import org.springframework.integration.support.channel.ChannelResolver;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * Base class for all Message Routers.
+ *
+ * @author Mark Fisher
+ * @author Oleg Zhurakousky
+ * @author Gunnar Hillert
+ * @since 2.1
+ */
+@ManagedResource
+public abstract class AbstractMappingMessageRouter extends AbstractMessageRouter {
+
+ private final Map channelMappings = new ConcurrentHashMap();
+
+ private volatile ChannelResolver channelResolver;
+
+ private volatile String prefix;
+
+ private volatile String suffix;
+
+ private volatile boolean resolutionRequired = true;
+
+
+ /**
+ * Provide mappings from channel keys to channel names.
+ * Channel names will be resolved by the {@link ChannelResolver}.
+ */
+ public void setChannelMappings(Map channelMappings) {
+ this.channelMappings.clear();
+ this.channelMappings.putAll(channelMappings);
+ }
+
+ /**
+ * Specify the {@link ChannelResolver} strategy to use.
+ * The default is a BeanFactoryChannelResolver.
+ */
+ public void setChannelResolver(ChannelResolver channelResolver) {
+ Assert.notNull(channelResolver, "'channelResolver' must not be null");
+ this.channelResolver = channelResolver;
+ }
+
+ /**
+ * Specify a prefix to be added to each channel name prior to resolution.
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * Specify a suffix to be added to each channel name prior to resolution.
+ */
+ public void setSuffix(String suffix) {
+ this.suffix = suffix;
+ }
+
+ /**
+ * Specify whether this router should ignore any failure to resolve a channel name to
+ * an actual MessageChannel instance when delegating to the ChannelResolver strategy.
+ */
+ public void setResolutionRequired(boolean resolutionRequired) {
+ this.resolutionRequired = resolutionRequired;
+ }
+
+ /**
+ * Returns an unmodifiable version of the channel mappings.
+ * This is intended for use by subclasses only.
+ */
+ protected Map getChannelMappings() {
+ return Collections.unmodifiableMap(this.channelMappings);
+ }
+
+ /**
+ * Add a channel mapping from the provided key to channel name.
+ */
+ @ManagedOperation
+ public void setChannelMapping(String key, String channelName) {
+ this.channelMappings.put(key, channelName);
+ }
+
+ /**
+ * Remove a channel mapping for the given key if present.
+ */
+ @ManagedOperation
+ public void removeChannelMapping(String key) {
+ this.channelMappings.remove(key);
+ }
+
+ @Override
+ public void onInit() {
+ BeanFactory beanFactory = this.getBeanFactory();
+ if (this.channelResolver == null && beanFactory != null) {
+ this.channelResolver = new BeanFactoryChannelResolver(beanFactory);
+ }
+ }
+
+ /**
+ * Subclasses must implement this method to return the channel keys.
+ * A "key" might be present in this router's "channelMappings", or it
+ * could be the channel's name or even the Message Channel instance itself.
+ */
+ protected abstract List