INT-703 Added support for inner consumer definition (beans:bean)

This commit is contained in:
Oleg Zhurakousky
2009-08-18 04:14:10 +00:00
parent 4168b49e49
commit 0aaa5f9915
5 changed files with 47 additions and 15 deletions

View File

@@ -18,29 +18,29 @@ package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
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.xml.ParserContext;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Parser for the <outbound-channel-adapter/> element.
*
* @author Mark Fisher
* @author Oleg Zhurakousky
*/
public class MethodInvokingOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
@Override
protected String parseAndRegisterConsumer(Element element, ParserContext parserContext) {
String consumerRef = element.getAttribute("ref");
if (!StringUtils.hasText(consumerRef)) {
parserContext.getReaderContext().error("The 'ref' attribute is required.", element);
}
if (element.hasAttribute("method")) {
String consumerRef = element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE);
if (element.hasAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE)) {
consumerRef = BeanDefinitionReaderUtils.registerWithGeneratedName(
this.parseConsumer(element, parserContext), parserContext.getRegistry());
}
Assert.notNull(consumerRef, "Can not determine consumer for outbound-channel-adapter");
return consumerRef;
}
@@ -48,11 +48,20 @@ public class MethodInvokingOutboundChannelAdapterParser extends AbstractOutbound
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder invokerBuilder = BeanDefinitionBuilder.genericBeanDefinition(
IntegrationNamespaceUtils.BASE_PACKAGE + ".handler.MethodInvokingMessageHandler");
invokerBuilder.addConstructorArgReference(element.getAttribute("ref"));
invokerBuilder.addConstructorArgValue(element.getAttribute("method"));
String order = element.getAttribute("order");
BeanDefinition innerHandlerDefinition =
IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
if (innerHandlerDefinition == null){
Assert.hasText(element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE),
"You must provide 'ref' attribute or register inner bean for " +
"Outbound Channel consumer.");
invokerBuilder.addConstructorArgReference(element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE));
} else {
invokerBuilder.addConstructorArgValue(innerHandlerDefinition);
}
invokerBuilder.addConstructorArgValue(element.getAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE));
String order = element.getAttribute(IntegrationNamespaceUtils.ORDER);
if (StringUtils.hasText(order)) {
invokerBuilder.addPropertyValue("order", order);
invokerBuilder.addPropertyValue(IntegrationNamespaceUtils.ORDER, order);
}
return invokerBuilder.getBeanDefinition();
}

View File

@@ -409,7 +409,7 @@
<xsd:complexType name="methodInvokingChannelAdapterType">
<xsd:complexContent>
<xsd:extension base="channelAdapterType">
<xsd:attribute name="ref" type="xsd:string" use="required">
<xsd:attribute name="ref" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
@@ -424,10 +424,11 @@
</xsd:complexType>
<xsd:complexType name="channelAdapterType">
<xsd:sequence>
<xsd:all>
<xsd:element name="poller" type="innerPollerType"
minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:element ref="beans:bean" minOccurs="0" maxOccurs="1" />
</xsd:all>
<xsd:attribute name="id" type="xsd:ID" />
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>

View File

@@ -5,7 +5,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
http://www.springframework.org/schema/integration/spring-integration.xsd">
<channel id="queueChannel">
<queue capacity="1"/>

View File

@@ -4,13 +4,24 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd">
<channel id="channel"/>
<channel id="channelB">
<queue capacity="2"/>
</channel>
<outbound-channel-adapter id="adapter" channel="channel" ref="bean" method="out" order="99" auto-startup="false"/>
<beans:bean id="bean"
class="org.springframework.integration.config.xml.MethodInvokingOutboundChannelAdapterParserTests$TestBean"/>
<outbound-channel-adapter id="adapterB" channel="channelB" method="out" order="99" auto-startup="false">
<beans:bean class="org.springframework.integration.config.xml.MethodInvokingOutboundChannelAdapterParserTests$TestBean"/>
<poller task-executor="executor" max-messages-per-poll="5">
<interval-trigger interval="20" />
</poller>
</outbound-channel-adapter>
<thread-pool-task-executor id="executor" core-size="5" />
</beans:beans>

View File

@@ -50,6 +50,17 @@ public class MethodInvokingOutboundChannelAdapterParserTests {
assertEquals(99, handlerAccessor.getPropertyValue("order"));
assertEquals(Boolean.FALSE, adapterAccessor.getPropertyValue("autoStartup"));
}
@Test
public void checkConfigWithInnerBeanAndPoller() {
Object adapter = context.getBean("adapterB");
DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter);
Object handler = adapterAccessor.getPropertyValue("handler");
assertEquals(MethodInvokingMessageHandler.class, handler.getClass());
DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(handler);
assertEquals(99, handlerAccessor.getPropertyValue("order"));
assertEquals(Boolean.FALSE, adapterAccessor.getPropertyValue("autoStartup"));
}
static class TestBean {