Annotation Interface EnableRabbit
RabbitListenerContainerFactory. To be used on
Configuration
classes as follows:
@Configuration
@EnableRabbit
public class AppConfig {
@Bean
public SimpleRabbitListenerContainerFactory myRabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setMaxConcurrentConsumers(5);
return factory;
}
// other @Bean definitions
}
The RabbitListenerContainerFactory is responsible to create the listener container
responsible for a particular endpoint. Typical implementations, as the
SimpleRabbitListenerContainerFactory
used in the sample above, provides the necessary configuration options that are supported by
the underlying MessageListenerContainer.
@EnableRabbit enables detection of RabbitListener annotations on any
Spring-managed bean in the container. For example, given a class MyService:
package com.acme.foo;
public class MyService {
@RabbitListener(containerFactory="myRabbitListenerContainerFactory", queues="myQueue")
public void process(String msg) {
// process incoming message
}
}
The container factory to use is identified by the containerFactory
attribute defining the name of the RabbitListenerContainerFactory bean to use. When none
is set a RabbitListenerContainerFactory bean with name rabbitListenerContainerFactory is
assumed to be present.
the following configuration would ensure that every time a Message
is received on the Queue named "myQueue", MyService.process()
is called with the content of the message:
@Configuration
@EnableRabbit
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
// Rabbit infrastructure setup
}
Alternatively, if MyService were annotated with @Component, the
following configuration would ensure that its @RabbitListener annotated
method is invoked with a matching incoming message:
@Configuration
@EnableRabbit
@ComponentScan(basePackages="com.acme.foo")
public class AppConfig {
}
Note that the created containers are not registered against the application context
but can be easily located for management purposes using the
RabbitListenerEndpointRegistry.
Annotated methods can use flexible signature; in particular, it is possible to use
the Message abstraction and related annotations,
see RabbitListener Javadoc for more details. For instance, the following would
inject the content of the message and a custom "myCounter" AMQP header:
@RabbitListener(containerFactory = "myRabbitListenerContainerFactory", queues = "myQueue")
public void process(String msg, @Header("myCounter") int counter) {
// process incoming message
}
These features are abstracted by the
MessageHandlerMethodFactory that is responsible to build the necessary invoker to process
the annotated method. By default,
DefaultMessageHandlerMethodFactory is used.
When more control is desired, a @Configuration class may implement
RabbitListenerConfigurer. This allows access to the underlying
RabbitListenerEndpointRegistrar
instance. The following example demonstrates how to specify an explicit default
RabbitListenerContainerFactory
@Configuration
@EnableRabbit
public class AppConfig implements RabbitListenerConfigurer {
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setContainerFactory(myRabbitListenerContainerFactory());
}
@Bean
public RabbitListenerContainerFactory<?> myRabbitListenerContainerFactory() {
// factory settings
}
@Bean
public MyService myService() {
return new MyService();
}
}
For reference, the example above can be compared to the following Spring XML
configuration:
<beans>
<rabbit:annotation-driven container-factory="myRabbitListenerContainerFactory"/>
<bean id="myRabbitListenerContainerFactory"
class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
// factory settings
</bean>
<bean id="myService" class="com.acme.foo.MyService"/>
</beans>
It is also possible to specify a custom RabbitListenerEndpointRegistry in case you need more control on the way the containers
are created and managed. The example below also demonstrates how to customize the
RabbitHandlerMethodFactory to use with a custom Validator so that payloads annotated with Validated are first validated against a custom Validator.
@Configuration
@EnableRabbit
public class AppConfig implements RabbitListenerConfigurer {
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setEndpointRegistry(myRabbitListenerEndpointRegistry());
registrar.setMessageHandlerMethodFactory(myMessageHandlerMethodFactory());
}
@Bean
public RabbitListenerEndpointRegistry<?> myRabbitListenerEndpointRegistry() {
// registry configuration
}
@Bean
public RabbitHandlerMethodFactory myMessageHandlerMethodFactory() {
DefaultRabbitHandlerMethodFactory factory = new DefaultRabbitHandlerMethodFactory();
factory.setValidator(new MyValidator());
return factory;
}
@Bean
public MyService myService() {
return new MyService();
}
}
For reference, the example above can be compared to the following Spring XML
configuration:
<beans>
<rabbit:annotation-driven registry="myRabbitListenerEndpointRegistry"
handler-method-factory="myRabbitHandlerMethodFactory"/>
<bean id="myRabbitListenerEndpointRegistry"
class="org.springframework.amqp.rabbit.config.RabbitListenerEndpointRegistry">
// registry configuration
</bean>
<bean id="myRabbitHandlerMethodFactory"
class="org.springframework.amqp.rabbit.config.DefaultRabbitHandlerMethodFactory">
<property name="validator" ref="myValidator"/>
</bean>
<bean id="myService" class="com.acme.foo.MyService"/>
</beans>
Implementing RabbitListenerConfigurer also allows for fine-grained
control over endpoints registration via the RabbitListenerEndpointRegistrar.
For example, the following configures an extra endpoint:
@Configuration
@EnableRabbit
public class AppConfig implements RabbitListenerConfigurer {
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
SimpleRabbitListenerEndpoint myEndpoint = new SimpleRabbitListenerEndpoint();
// ... configure the endpoint
registrar.registerEndpoint(endpoint, anotherRabbitListenerContainerFactory());
}
@Bean
public MyService myService() {
return new MyService();
}
@Bean
public RabbitListenerContainerFactory<?> anotherRabbitListenerContainerFactory() {
// ...
}
// Rabbit infrastructure setup
}
Note that all beans implementing RabbitListenerConfigurer will be detected and
invoked in a similar fashion. The example above can be translated in a regular bean
definition registered in the context in case you use the XML configuration.- Since:
- 1.4
- Author:
- Stephane Nicoll, Artem Bilan
- See Also: