@Target([AnnotationTarget.CLASS, AnnotationTarget.FILE]) @Import(JmsBootstrapConfiguration) class EnableJms
Enable JMS listener annotated endpoints that are created under the cover by a org.springframework.jms.config.JmsListenerContainerFactory. To be used on org.springframework.context.annotation.Configuration classes as follows:
@Configuration @EnableJms public class AppConfig { @Bean public DefaultJmsListenerContainerFactory myJmsListenerContainerFactory() { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); factory.setDestinationResolver(destinationResolver()); factory.setConcurrency("5"); return factory; } // other @Bean definitions }
The JmsListenerContainerFactory
is responsible to create the listener container responsible for a particular endpoint. Typical implementations, as the org.springframework.jms.config.DefaultJmsListenerContainerFactory used in the sample above, provides the necessary configuration options that are supported by the underlying org.springframework.jms.listener.MessageListenerContainer.
@EnableJms
enables detection of JmsListener annotations on any Spring-managed bean in the container. For example, given a class MyService
:
package com.acme.foo; public class MyService { @JmsListener(containerFactory = "myJmsListenerContainerFactory", destination="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 JmsListenerContainerFactory
bean to use. When none is set a JmsListenerContainerFactory
bean with name jmsListenerContainerFactory
is assumed to be present.
the following configuration would ensure that every time a javax.jms.Message is received on the javax.jms.Destination named "myQueue", MyService.process()
is called with the content of the message:
@Configuration @EnableJms public class AppConfig { @Bean public MyService myService() { return new MyService(); } // JMS infrastructure setup }
Alternatively, if MyService
were annotated with @Component
, the following configuration would ensure that its @JmsListener
annotated method is invoked with a matching incoming message: @Configuration @EnableJms @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 org.springframework.jms.config.JmsListenerEndpointRegistry.
Annotated methods can use flexible signature; in particular, it is possible to use the org.springframework.messaging.Message abstraction and related annotations, see JmsListener Javadoc for more details. For instance, the following would inject the content of the message and a custom "myCounter" JMS header:
@JmsListener(containerFactory = "myJmsListenerContainerFactory", destination="myQueue") public void process(String msg, @Header("myCounter") int counter) { // process incoming message }
These features are abstracted by the org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory that is responsible to build the necessary invoker to process the annotated method. By default, org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory is used.
When more control is desired, a @Configuration
class may implement JmsListenerConfigurer. This allows access to the underlying org.springframework.jms.config.JmsListenerEndpointRegistrar instance. The following example demonstrates how to specify an explicit default JmsListenerContainerFactory
@Configuration @EnableJms public class AppConfig implements JmsListenerConfigurer { @Override public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) { registrar.setContainerFactory(myJmsListenerContainerFactory()); } @Bean public JmsListenerContainerFactory myJmsListenerContainerFactory() { // factory settings } @Bean public MyService myService() { return new MyService(); } }
For reference, the example above can be compared to the following Spring XML configuration: <beans> <jms:annotation-driven container-factory="myJmsListenerContainerFactory"/> <bean id="myJmsListenerContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory"> // factory settings </bean> <bean id="myService" class="com.acme.foo.MyService"/> </beans>
It is also possible to specify a custom org.springframework.jms.config.JmsListenerEndpointRegistry in case you need more control on the way the containers are created and managed. The example below also demonstrates how to customize the JmsHandlerMethodFactory
to use with a custom org.springframework.validation.Validator so that payloads annotated with org.springframework.validation.annotation.Validated are first validated against a custom Validator
. @Configuration @EnableJms public class AppConfig implements JmsListenerConfigurer { @Override public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) { registrar.setEndpointRegistry(myJmsListenerEndpointRegistry()); registrar.setMessageHandlerMethodFactory(myJmsHandlerMethodFactory); } @Bean public JmsListenerEndpointRegistry myJmsListenerEndpointRegistry() { // registry configuration } @Bean public JmsHandlerMethodFactory myJmsHandlerMethodFactory() { DefaultJmsHandlerMethodFactory factory = new DefaultJmsHandlerMethodFactory(); 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> <jms:annotation-driven registry="myJmsListenerEndpointRegistry" handler-method-factory="myJmsHandlerMethodFactory"/> <bean id="myJmsListenerEndpointRegistry" class="org.springframework.jms.config.JmsListenerEndpointRegistry"> // registry configuration </bean> <bean id="myJmsHandlerMethodFactory" class="org.springframework.messaging.handler.support.DefaultJmsHandlerMethodFactory"> <property name="validator" ref="myValidator"/> </bean> <bean id="myService" class="com.acme.foo.MyService"/> </beans>
Implementing JmsListenerConfigurer
also allows for fine-grained control over endpoints registration via the JmsListenerEndpointRegistrar
. For example, the following configures an extra endpoint: @Configuration @EnableJms public class AppConfig implements JmsListenerConfigurer { @Override public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) { SimpleJmsListenerEndpoint myEndpoint = new SimpleJmsListenerEndpoint(); // ... configure the endpoint registrar.registerEndpoint(endpoint, anotherJmsListenerContainerFactory()); } @Bean public MyService myService() { return new MyService(); } @Bean public JmsListenerContainerFactory anotherJmsListenerContainerFactory() { // ... } // JMS infrastructure setup }
Note that all beans implementing JmsListenerConfigurer
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.
Author
Stephane Nicoll
Since
4.1
See Also
JmsListenerJmsListenerAnnotationBeanPostProcessororg.springframework.jms.config.JmsListenerEndpointRegistrarorg.springframework.jms.config.JmsListenerEndpointRegistry
EnableJms()
Enable JMS listener annotated endpoints that are created under the cover by a org.springframework.jms.config.JmsListenerContainerFactory. To be used on org.springframework.context.annotation.Configuration classes as follows: The JmsListenerContainerFactory is responsible to create the listener container responsible for a particular endpoint. Typical implementations, as the org.springframework.jms.config.DefaultJmsListenerContainerFactory used in the sample above, provides the necessary configuration options that are supported by the underlying org.springframework.jms.listener.MessageListenerContainer.
The container factory to use is identified by the containerFactory attribute defining the name of the JmsListenerContainerFactory bean to use. When none is set a JmsListenerContainerFactory bean with name jmsListenerContainerFactory is assumed to be present.
the following configuration would ensure that every time a javax.jms.Message is received on the javax.jms.Destination named "myQueue", Alternatively, if MyService were annotated with @Component , the following configuration would ensure that its @JmsListener annotated method is invoked with a matching incoming message: Note that the created containers are not registered against the application context but can be easily located for management purposes using the org.springframework.jms.config.JmsListenerEndpointRegistry.
Annotated methods can use flexible signature; in particular, it is possible to use the org.springframework.messaging.Message abstraction and related annotations, see JmsListener Javadoc for more details. For instance, the following would inject the content of the message and a custom "myCounter" JMS header: These features are abstracted by the org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory that is responsible to build the necessary invoker to process the annotated method. By default, org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory is used.
When more control is desired, a For reference, the example above can be compared to the following Spring XML configuration: It is also possible to specify a custom org.springframework.jms.config.JmsListenerEndpointRegistry in case you need more control on the way the containers are created and managed. The example below also demonstrates how to customize the JmsHandlerMethodFactory to use with a custom org.springframework.validation.Validator so that payloads annotated with org.springframework.validation.annotation.Validated are first validated against a custom Validator . For reference, the example above can be compared to the following Spring XML configuration: Implementing JmsListenerConfigurer also allows for fine-grained control over endpoints registration via the JmsListenerEndpointRegistrar . For example, the following configures an extra endpoint: Note that all beans implementing JmsListenerConfigurer 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.
|