diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/ChannelAdapterParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/ChannelAdapterParser.java index f6429d424a..3f08501cc6 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/ChannelAdapterParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/ChannelAdapterParser.java @@ -23,12 +23,15 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.ConfigurationException; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.endpoint.InboundChannelAdapter; import org.springframework.integration.endpoint.OutboundChannelAdapter; +import org.springframework.integration.handler.MethodInvokingTarget; +import org.springframework.integration.message.MethodInvokingSource; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; @@ -57,12 +60,16 @@ public class ChannelAdapterParser extends AbstractBeanDefinitionParser { String source = element.getAttribute("source"); String target = element.getAttribute("target"); String channelName = element.getAttribute("channel"); + String methodName = element.getAttribute("method"); Element pollerElement = DomUtils.getChildElementByTagName(element, "poller"); BeanDefinitionBuilder adapterBuilder = null; if (StringUtils.hasText(source)) { if (StringUtils.hasText(target)) { throw new ConfigurationException("both 'source' and 'target' are not allowed, provide only one"); } + if (StringUtils.hasText(methodName)) { + source = parseMethodInvokingAdapter(source, methodName, MethodInvokingSource.class, parserContext.getRegistry()); + } adapterBuilder = BeanDefinitionBuilder.genericBeanDefinition(InboundChannelAdapter.class); if (pollerElement != null) { String pollerBeanName = IntegrationNamespaceUtils.parsePoller(source, pollerElement, parserContext); @@ -80,6 +87,9 @@ public class ChannelAdapterParser extends AbstractBeanDefinitionParser { } } else if (StringUtils.hasText(target)) { + if (StringUtils.hasText(methodName)) { + target = this.parseMethodInvokingAdapter(target, methodName, MethodInvokingTarget.class, parserContext.getRegistry()); + } adapterBuilder = BeanDefinitionBuilder.genericBeanDefinition(OutboundChannelAdapter.class); adapterBuilder.addPropertyReference("target", target); if (pollerElement != null) { @@ -103,6 +113,13 @@ public class ChannelAdapterParser extends AbstractBeanDefinitionParser { return adapterBuilder.getBeanDefinition(); } + private String parseMethodInvokingAdapter(String objectRef, String methodName, Class type, BeanDefinitionRegistry registry) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(type); + builder.addPropertyReference("object", objectRef); + builder.addPropertyValue("methodName", methodName); + return BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), registry); + } + private String createDirectChannel(Element element, ParserContext parserContext) { String channelId = element.getAttribute("id"); if (!StringUtils.hasText(channelId)) { diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd index d996c79aea..603d87db4b 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd @@ -166,6 +166,7 @@ + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml index a9335910a3..a7b7ebbedb 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml @@ -7,10 +7,20 @@ http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-core-1.0.xsd"> - + + + + + + + + + + + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests.java index 726ac1f086..e0307571a3 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests.java @@ -17,8 +17,8 @@ package org.springframework.integration.config; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -26,6 +26,8 @@ import org.junit.Test; import org.springframework.integration.bus.MessageBus; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.MessageChannel; +import org.springframework.integration.channel.PollableChannel; +import org.springframework.integration.endpoint.InboundChannelAdapter; import org.springframework.integration.endpoint.OutboundChannelAdapter; import org.springframework.integration.message.Message; import org.springframework.integration.message.StringMessage; @@ -44,6 +46,7 @@ public class ChannelAdapterParserTests extends AbstractJUnit4SpringContextTests Object channel = this.applicationContext.getBean(beanName); assertTrue(channel instanceof DirectChannel); MessageBus bus = (MessageBus) this.applicationContext.getBean(MessageBusParser.MESSAGE_BUS_BEAN_NAME); + bus.start(); assertNotNull(bus.lookupChannel(beanName)); Object adapter = bus.lookupEndpoint(beanName + ".adapter"); assertNotNull(adapter); @@ -54,6 +57,45 @@ public class ChannelAdapterParserTests extends AbstractJUnit4SpringContextTests assertTrue(((MessageChannel) channel).send(message)); assertNotNull(target.getLastMessage()); assertEquals(message, target.getLastMessage()); + bus.stop(); + } + + @Test + public void methodInvokingTarget() { + String beanName = "methodInvokingTarget"; + Object channel = this.applicationContext.getBean(beanName); + assertTrue(channel instanceof DirectChannel); + MessageBus bus = (MessageBus) this.applicationContext.getBean(MessageBusParser.MESSAGE_BUS_BEAN_NAME); + bus.start(); + assertNotNull(bus.lookupChannel(beanName)); + Object adapter = bus.lookupEndpoint(beanName + ".adapter"); + assertNotNull(adapter); + assertTrue(adapter instanceof OutboundChannelAdapter); + TestBean testBean = (TestBean) this.applicationContext.getBean("testBean"); + assertNull(testBean.getMessage()); + Message message = new StringMessage("target test"); + assertTrue(((MessageChannel) channel).send(message)); + assertNotNull(testBean.getMessage()); + assertEquals("target test", testBean.getMessage()); + bus.stop(); + } + + @Test + public void methodInvokingSource() { + String beanName = "methodInvokingSource"; + PollableChannel channel = (PollableChannel) this.applicationContext.getBean("queueChannel"); + MessageBus bus = (MessageBus) this.applicationContext.getBean(MessageBusParser.MESSAGE_BUS_BEAN_NAME); + assertNull(bus.lookupChannel(beanName)); + Object adapter = bus.lookupEndpoint(beanName); + assertNotNull(adapter); + assertTrue(adapter instanceof InboundChannelAdapter); + TestBean testBean = (TestBean) this.applicationContext.getBean("testBean"); + testBean.store("source test"); + bus.start(); + Message message = channel.receive(1000); + assertNotNull(message); + assertEquals("source test", testBean.getMessage()); + bus.stop(); } } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/TestBean.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/TestBean.java index 83845b3ad6..65d3907754 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/TestBean.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/TestBean.java @@ -30,6 +30,10 @@ public class TestBean { private String replyMessageText = null; + public TestBean() { + this(1); + } + public TestBean(int countdown) { this.latch = new CountDownLatch(countdown); }