AMQP-147: added <rabbit:template/> and <rabbit:connection-factory/> (the latter is more useful)

This commit is contained in:
Dave Syer
2011-04-06 13:19:58 +01:00
parent c84fe783c3
commit 666c51a6b9
10 changed files with 528 additions and 59 deletions

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2010-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.amqp.rabbit.config;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
/**
* @author Dave Syer
*/
class ConnectionFactoryParser extends AbstractSingleBeanDefinitionParser {
private static final String CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
private static final String CHANNEL_CACHE_SIZE_ATTRIBUTE = "channel-cache-size";
private static final String HOST_ATTRIBUTE = "host";
private static final String PORT_ATTRIBUTE = "port";
private static final String VIRTUAL_HOST_ATTRIBUTE = "virtual-host";
private static final String USER_ATTRIBUTE = "username";
private static final String PASSWORD_ATTRIBUTE = "password";
@Override
protected Class<?> getBeanClass(Element element) {
return CachingConnectionFactory.class;
}
@Override
protected boolean shouldGenerateId() {
return false;
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
NamespaceUtils.addConstructorArgParentRefIfAttributeDefined(builder, element, CONNECTION_FACTORY_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, CHANNEL_CACHE_SIZE_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, HOST_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, PORT_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, USER_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, PASSWORD_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, VIRTUAL_HOST_ATTRIBUTE);
}
}

View File

@@ -49,12 +49,14 @@ public abstract class NamespaceUtils {
* @param attributeName the name of the attribute whose value will be used to populate the property
* @param propertyName the name of the property to be populated
*/
public static void setValueIfAttributeDefined(BeanDefinitionBuilder builder, Element element, String attributeName,
String propertyName) {
public static boolean setValueIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
String attributeName, String propertyName) {
String attributeValue = element.getAttribute(attributeName);
if (StringUtils.hasText(attributeValue)) {
builder.addPropertyValue(propertyName, attributeValue);
return true;
}
return false;
}
/**
@@ -71,8 +73,9 @@ public abstract class NamespaceUtils {
* @param element the XML element where the attribute should be defined
* @param attributeName the name of the attribute whose value will be set on the property
*/
public static void setValueIfAttributeDefined(BeanDefinitionBuilder builder, Element element, String attributeName) {
setValueIfAttributeDefined(builder, element, attributeName,
public static boolean setValueIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
String attributeName) {
return setValueIfAttributeDefined(builder, element, attributeName,
Conventions.attributeNameToPropertyName(attributeName));
}
@@ -95,17 +98,19 @@ public abstract class NamespaceUtils {
* @param element the XML element where the attribute should be defined
* @param attributeName the name of the attribute whose value will be used as a constructor argument
*/
public static void addConstructorArgValueIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
public static boolean addConstructorArgValueIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
String attributeName) {
String value = element.getAttribute(attributeName);
if (StringUtils.hasText(value)) {
builder.addConstructorArgValue(new TypedStringValue(value));
return true;
}
return false;
}
/**
* Populates the bean definition constructor argument with the boolean value of that attribute if it is defined in the given
* element or else uses the default provided.
* Populates the bean definition constructor argument with the boolean value of that attribute if it is defined in
* the given element or else uses the default provided.
*
* @param builder the bean definition builder to be configured
* @param element the XML element where the attribute should be defined
@@ -130,12 +135,34 @@ public abstract class NamespaceUtils {
* @param element the XML element where the attribute should be defined
* @param attributeName the name of the attribute whose value will be used to set the reference
*/
public static void addConstructorArgRefIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
public static boolean addConstructorArgRefIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
String attributeName) {
String value = element.getAttribute(attributeName);
if (StringUtils.hasText(value)) {
builder.addConstructorArgReference(value);
return true;
}
return false;
}
/**
* Populates the bean definition constructor argument with a reference to a bean with parent id equal to the
* attribute if it is defined in the given element.
*
* @param builder the bean definition builder to be configured
* @param element the XML element where the attribute should be defined
* @param attributeName the name of the attribute whose value will be used to set the reference
*/
public static boolean addConstructorArgParentRefIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
String attributeName) {
String value = element.getAttribute(attributeName);
if (StringUtils.hasText(value)) {
BeanDefinitionBuilder child = BeanDefinitionBuilder.genericBeanDefinition();
child.setParentName(value);
builder.addConstructorArgValue(child.getBeanDefinition());
return true;
}
return false;
}
/**
@@ -147,13 +174,16 @@ public abstract class NamespaceUtils {
* @param attributeName the name of the attribute whose value will be used as a bean reference to populate the
* property
* @param propertyName the name of the property to be populated
* @return
*/
public static void setReferenceIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
public static boolean setReferenceIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
String attributeName, String propertyName) {
String attributeValue = element.getAttribute(attributeName);
if (StringUtils.hasText(attributeValue)) {
builder.addPropertyReference(propertyName, attributeValue);
return true;
}
return false;
}
/**
@@ -173,9 +203,9 @@ public abstract class NamespaceUtils {
*
* @see Conventions#attributeNameToPropertyName(String)
*/
public static void setReferenceIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
public static boolean setReferenceIfAttributeDefined(BeanDefinitionBuilder builder, Element element,
String attributeName) {
setReferenceIfAttributeDefined(builder, element, attributeName,
return setReferenceIfAttributeDefined(builder, element, attributeName,
Conventions.attributeNameToPropertyName(attributeName));
}

View File

@@ -35,6 +35,8 @@ public class RabbitNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("headers-exchange", new HeadersExchangeParser());
registerBeanDefinitionParser("listener-container", new ListenerContainerParser());
registerBeanDefinitionParser("admin", new AdminParser());
registerBeanDefinitionParser("connection-factory", new ConnectionFactoryParser());
registerBeanDefinitionParser("template", new TemplateParser());
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2010-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.amqp.rabbit.config;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Dave Syer
*/
class TemplateParser extends AbstractSingleBeanDefinitionParser {
private static final String CONNECTION_FACTORY_ATTRIBUTE = "connection-factory";
private static final String EXCHANGE_ATTRIBUTE = "exchange";
private static final String QUEUE_ATTRIBUTE = "queue";
private static final String ROUTING_KEY_ATTRIBUTE = "routing-key";
private static final String REPLY_TIMEOUT_ATTRIBUTE = "reply-timeout";
private static final String MESSAGE_CONVERTER_ATTRIBUTE = "message-converter";
private static final String ENCODING_ATTRIBUTE = "encoding";
private static final String CHANNEL_TRANSACTED_ATTRIBUTE = "channel-transacted";
@Override
protected Class<?> getBeanClass(Element element) {
return RabbitTemplate.class;
}
@Override
protected boolean shouldGenerateId() {
return false;
}
@Override
protected boolean shouldGenerateIdAsFallback() {
return true;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String connectionFactoryRef = element.getAttribute(CONNECTION_FACTORY_ATTRIBUTE);
if (!StringUtils.hasText(connectionFactoryRef)) {
parserContext.getReaderContext().error("A '" + CONNECTION_FACTORY_ATTRIBUTE + "' attribute must be set.",
element);
}
if (StringUtils.hasText(connectionFactoryRef)) {
// Use constructor with connectionFactory parameter
builder.addConstructorArgReference(connectionFactoryRef);
}
NamespaceUtils.setValueIfAttributeDefined(builder, element, CHANNEL_TRANSACTED_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, QUEUE_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, EXCHANGE_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, ROUTING_KEY_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, REPLY_TIMEOUT_ATTRIBUTE);
NamespaceUtils.setValueIfAttributeDefined(builder, element, ENCODING_ATTRIBUTE);
NamespaceUtils.setReferenceIfAttributeDefined(builder, element, MESSAGE_CONVERTER_ATTRIBUTE);
}
}

View File

@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.org/schema/rabbit"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tool="http://www.springframework.org/schema/tool" xmlns:beans="http://www.springframework.org/schema/beans"
targetNamespace="http://www.springframework.org/schema/rabbit"
<xsd:schema xmlns="http://www.springframework.org/schema/rabbit" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.springframework.org/schema/rabbit"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" />
@@ -18,8 +17,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="queue-arguments" minOccurs="0"
maxOccurs="1" />
<xsd:element ref="queue-arguments" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
@@ -92,8 +90,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="binding" maxOccurs="unbounded"
type="directBindingType">
<xsd:element name="binding" maxOccurs="unbounded" type="directBindingType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Declares a binding of a queue to this exchange either with
@@ -133,8 +130,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="binding" maxOccurs="unbounded"
type="topicBindingType">
<xsd:element name="binding" maxOccurs="unbounded" type="topicBindingType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Declares a binding of a queue to this exchange either with
@@ -172,8 +168,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="binding" maxOccurs="unbounded"
type="bindingType">
<xsd:element name="binding" maxOccurs="unbounded" type="bindingType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Binds a queue to this exchange. All messages sent to this exchange will be
@@ -212,8 +207,7 @@
</xsd:annotation>
<xsd:complexType>
<xsd:choice>
<xsd:element name="binding" maxOccurs="unbounded"
type="headersBindingType">
<xsd:element name="binding" maxOccurs="unbounded" type="headersBindingType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Binds a queue to this exchange. Messages sent to this exchange will be
@@ -233,8 +227,7 @@
<xsd:complexType name="exchangeType">
<xsd:sequence>
<xsd:element ref="exchange-arguments" minOccurs="0"
maxOccurs="1" />
<xsd:element ref="exchange-arguments" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
@@ -251,16 +244,14 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="auto-delete" use="optional" type="xsd:boolean"
default="false">
<xsd:attribute name="auto-delete" use="optional" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Flag indicating that an exchange will be deleted when no longer in use, i.e. the connection that declared it is closed. Default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="durable" use="optional" type="xsd:boolean"
default="false">
<xsd:attribute name="durable" use="optional" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Flag indicating that the exchange is durable, i.e. will survive broker restart. Default is false.
@@ -320,8 +311,7 @@
<xsd:complexType name="bindingType">
<xsd:sequence>
<xsd:element ref="binding-arguments" minOccurs="0"
maxOccurs="1" />
<xsd:element ref="binding-arguments" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="queue" use="required">
<xsd:annotation>
@@ -373,13 +363,13 @@
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer"/>
<tool:exports type="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="listener" type="listenerType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="listener" type="listenerType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
@@ -396,7 +386,7 @@
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.amqp.rabbit.connection.ConnectionFactory"/>
<tool:expected-type type="org.springframework.amqp.rabbit.connection.ConnectionFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
@@ -409,7 +399,7 @@
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="java.util.concurrent.Executor"/>
<tool:expected-type type="java.util.concurrent.Executor" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
@@ -423,7 +413,7 @@
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.amqp.support.converter.MessageConverter"/>
<tool:expected-type type="org.springframework.amqp.support.converter.MessageConverter" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
@@ -436,7 +426,7 @@
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.util.ErrorHandler"/>
<tool:expected-type type="org.springframework.util.ErrorHandler" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
@@ -449,9 +439,9 @@
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="auto"/>
<xsd:enumeration value="manual"/>
<xsd:enumeration value="none"/>
<xsd:enumeration value="auto" />
<xsd:enumeration value="manual" />
<xsd:enumeration value="none" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
@@ -462,7 +452,7 @@
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.transaction.PlatformTransactionManager"/>
<tool:expected-type type="org.springframework.transaction.PlatformTransactionManager" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
@@ -540,7 +530,7 @@
or defining the specified listener method. Required.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
<tool:annotation kind="ref" />
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
@@ -600,8 +590,7 @@
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.amqp.rabbit.connection.ConnectionFactory" />
<tool:expected-type type="org.springframework.amqp.rabbit.connection.ConnectionFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
@@ -615,4 +604,161 @@
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="template">
<xsd:annotation>
<xsd:documentation><![CDATA[
Creates a rabbit template (org.springframework.amqp.rabbit.core.RabbitTemplate)
for convenient access to the broker.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Unique name for this rabbit template used as a bean definition identifier.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="routing-key" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Default routing key for sending messages. Default is empty.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="exchange" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Default exchange for sending messages. Default is empty (the default exchange).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="queue" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Default queue for receiving messages. Default is empty (non-existent queue).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="reply-timeout" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Timeout for send and receive in milliseconds. Default is 5000 (5 seconds).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel-transacted" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Flag to indicate that the channel should be used transactionally. Default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="encoding" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Encoding to use for packing and unpacking MessagePoperties of type String. Default is UTF-8.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="message-converter" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
MessageConverter to convert between raw bytes and Java objects in the *convert* methods. Defaults to a simple implementation that handles Strings, byte arrays and Serializable.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.amqp.support.converter.MessageConverter" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connection-factory" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to rabbit connection factory.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.amqp.rabbit.connection.ConnectionFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="connection-factory">
<xsd:annotation>
<xsd:documentation><![CDATA[
Creates a rabbit CachingConnectionFactory with sensible defaults.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Unique name for this rabbit connection factory used as a bean definition identifier.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Hostname to connect to broker. Default is "localhost".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Port number to connect to broker. Default is 5672.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="username" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Username to connect to broker. Default is "guest".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="password" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Password to connect to broker. Default is "guest".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="virtual-host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Virtual host name to connect to broker. Default is "/". Virtual hosts are logical partitions of the broker with separate queues, excchanges, users, etc.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel-cache-size" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Cache size for channels. More channels can be used by clients, but in excess of this number they will not be cached.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connection-factory" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to native rabbit connection factory, where you can specify native features like heartbeat. The other properties (host, port) etc. on this element
override the ones on the native connection factory (which is used as a parent bean definition).
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="com.rabbitmq.client.ConnectionFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2010-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.amqp.rabbit.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
*
* @author Dave Syer
*
*/
public final class ConnectionFactoryParserTests {
private XmlBeanFactory beanFactory;
@Before
public void setUpDefaultBeanFactory() throws Exception {
beanFactory = new XmlBeanFactory(new ClassPathResource(getClass().getSimpleName() + "-context.xml", getClass()));
}
@Test
public void testKitchenSink() throws Exception {
CachingConnectionFactory connectionFactory = beanFactory.getBean("kitchenSink", CachingConnectionFactory.class);
assertNotNull(connectionFactory);
assertEquals(10, connectionFactory.getChannelCacheSize());
}
@Test
public void testNative() throws Exception {
CachingConnectionFactory connectionFactory = beanFactory.getBean("native", CachingConnectionFactory.class);
assertNotNull(connectionFactory);
assertEquals(10, connectionFactory.getChannelCacheSize());
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2010-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.amqp.rabbit.config;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.SerializerMessageConverter;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/**
*
* @author Dave Syer
*
*/
public final class TemplateParserTests {
private XmlBeanFactory beanFactory;
@Before
public void setUpDefaultBeanFactory() throws Exception {
beanFactory = new XmlBeanFactory(new ClassPathResource(getClass().getSimpleName() + "-context.xml", getClass()));
}
@Test
public void testTemplate() throws Exception {
AmqpTemplate template = beanFactory.getBean("template", AmqpTemplate.class);
assertNotNull(template);
}
@Test
public void testKitchenSink() throws Exception {
RabbitTemplate template = beanFactory.getBean("kitchenSink", RabbitTemplate.class);
assertNotNull(template);
assertTrue(template.getMessageConverter() instanceof SerializerMessageConverter);
}
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<rabbit:connection-factory id="kitchenSink" host="foo" virtual-host="/bar"
channel-cache-size="10" port="6888" username="user" password="password" />
<rabbit:connection-factory id="native" connection-factory="connectionFactory" channel-cache-size="10" />
<bean id="connectionFactory" class="com.rabbitmq.client.ConnectionFactory"/>
</beans>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<rabbit:template id="template" connection-factory="connectionFactory" />
<rabbit:template id="kitchenSink" connection-factory="connectionFactory" channel-transacted="true"
encoding="UTF-8" exchange="foo" queue="bar" routing-key="spam" message-converter="converter" reply-timeout="1000" />
<rabbit:connection-factory id="connectionFactory" />
<bean id="converter" class="org.springframework.amqp.support.converter.SerializerMessageConverter"/>
</beans>

View File

@@ -242,7 +242,8 @@ Connection connection = connectionFactory.createConnection();]]></programlisting
<para>When using XML, the configuration might look like this:</para>
<programlisting language="xml"><![CDATA[<bean id="cf" class="org.springframework.amqp.rabbit.connection.SingleConnectionFactory">
<programlisting language="xml"><![CDATA[<bean id="connectionFactory"
class="org.springframework.amqp.rabbit.connection.SingleConnectionFactory">
<constructor-arg value="somehost"/>
<property name="username" value="guest"/>
<property name="password" value="guest"/>
@@ -266,7 +267,12 @@ Connection connection = connectionFactory.createConnection();]]></programlisting
<classname>SingleConnectionFactory</classname>
as useful for simple tests and maybe as a building block for extending the framework.
</note></para>
</note> A <classname>ConnectionFactory</classname> can be created
quickly and conveniently using the rabbit namespace: <programlisting
language="xml"><![CDATA[<rabbit:connection-factory id="connectionFactory"/>]]></programlisting>
In most cases this will be preferable since the framework can choose the
best defaults for you, and it will always choose a
<classname>CachingConnectionFactory</classname>.</para>
</section>
<section id="amqp-template">
@@ -692,13 +698,9 @@ Object receiveAndConvert(String queueName) throws AmqpException;]]></programlist
<para>The RabbitMQ implementation of this interface is RabbitAdmin which
when configured using Spring XML would look like this:<programlisting
language="xml"><![CDATA[<bean id="cf" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<constructor-arg value="localhost"/>
<property name="username" value="guest"/>
<property name="password" value="guest"/>
</bean>
language="xml"><![CDATA[<rabbit:connection-factory id="connectionFactory"/>
<rabbit:admin id="amqpAdmin" connection-factory="cf"/>]]></programlisting></para>
<rabbit:admin id="amqpAdmin" connection-factory="connectionFactory"/>]]></programlisting></para>
<para>The <classname>RabbitAdmin</classname> implementation does automatic
lazy declaration of <classname>Queues</classname>,
@@ -733,10 +735,11 @@ Object receiveAndConvert(String queueName) throws AmqpException;]]></programlist
<programlisting><![CDATA[<rabbit:queue name="stocks.trade.queue"/>]]></programlisting>
<para>To see how to use Java to configure the AMQP infrastructure, look at
the Stock sample application, there is the <code>@Configuration</code> class
<classname>AbstractStockRabbitConfiguration</classname> which in turn has
RabbitClientConfiguration and RabbitServerConfiguration subclasses. The
code for AbstractStockRabbitConfiguration is show below</para>
the Stock sample application, there is the <code>@Configuration</code>
class <classname>AbstractStockRabbitConfiguration</classname> which in
turn has RabbitClientConfiguration and RabbitServerConfiguration
subclasses. The code for AbstractStockRabbitConfiguration is show
below</para>
<programlisting language="java"><![CDATA[@Configuration
public abstract class AbstractStockAppRabbitConfiguration {
@@ -1078,5 +1081,4 @@ public class ExampleExternalTransactionAmqpConfiguration {
</tgroup>
</table></para>
</section>
</chapter>