org.springframework.jms.annotation

Annotation Type EnableJms



  • @Target(value=TYPE)
     @Retention(value=RUNTIME)
     @Documented
     @Import(value=JmsBootstrapConfiguration.class)
    public @interface EnableJms
    Enable JMS listener annotated endpoints that are created under the cover by a JmsListenerContainerFactory. To be used on Configuration classes as follows:
     @Configuration
     @EnableJms
     public class AppConfig {
    
         @Bean
         public DefaultJmsListenerContainerFactory myJmsListenerContainerFactory() {
           DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
           factory.setConnectionFactory(connectionFactory());
           factory.setDestinationResolver(destinationResolver());
           factory.setSessionTransacted(true);
           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 DefaultJmsListenerContainerFactory used in the sample above, provides the necessary configuration options that are supported by the underlying 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 Message is received on the 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 JmsListenerEndpointRegistry.

    Annotated methods can use flexible signature; in particular, it is possible to use the 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 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 JmsListenerConfigurer. This allows access to the underlying 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 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 Validator so that payloads annotated with 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.
    Since:
    4.1
    Author:
    Stephane Nicoll
    See Also:
    JmsListener, JmsListenerAnnotationBeanPostProcessor, JmsListenerEndpointRegistrar, JmsListenerEndpointRegistry