001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.jms.annotation;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Repeatable;
022import java.lang.annotation.Retention;
023import java.lang.annotation.RetentionPolicy;
024import java.lang.annotation.Target;
025
026import org.springframework.messaging.handler.annotation.MessageMapping;
027
028/**
029 * Annotation that marks a method to be the target of a JMS message listener on the
030 * specified {@link #destination}. The {@link #containerFactory} identifies the
031 * {@link org.springframework.jms.config.JmsListenerContainerFactory} to use to build
032 * the JMS listener container. If not set, a <em>default</em> container factory is
033 * assumed to be available with a bean name of {@code jmsListenerContainerFactory}
034 * unless an explicit default has been provided through configuration.
035 *
036 * <p><b>Consider setting up a custom
037 * {@link org.springframework.jms.config.DefaultJmsListenerContainerFactory} bean.</b>
038 * For production purposes, you'll typically fine-tune timeouts and recovery settings.
039 * Most importantly, the default 'AUTO_ACKNOWLEDGE' mode does not provide reliability
040 * guarantees, so make sure to use transacted sessions in case of reliability needs.
041 *
042 * <p>Processing of {@code @JmsListener} annotations is performed by registering a
043 * {@link JmsListenerAnnotationBeanPostProcessor}. This can be done manually or,
044 * more conveniently, through the {@code <jms:annotation-driven/>} element or
045 * {@link EnableJms @EnableJms} annotation.
046 *
047 * <p>Annotated JMS listener methods are allowed to have flexible signatures similar
048 * to what {@link MessageMapping} provides:
049 * <ul>
050 * <li>{@link javax.jms.Session} to get access to the JMS session</li>
051 * <li>{@link javax.jms.Message} or one of its subclasses to get access to the raw JMS message</li>
052 * <li>{@link org.springframework.messaging.Message} to use Spring's messaging abstraction counterpart</li>
053 * <li>{@link org.springframework.messaging.handler.annotation.Payload @Payload}-annotated method
054 * arguments, including support for validation</li>
055 * <li>{@link org.springframework.messaging.handler.annotation.Header @Header}-annotated method
056 * arguments to extract specific header values, including standard JMS headers defined by
057 * {@link org.springframework.jms.support.JmsHeaders}</li>
058 * <li>{@link org.springframework.messaging.handler.annotation.Headers @Headers}-annotated
059 * method argument that must also be assignable to {@link java.util.Map} for obtaining
060 * access to all headers</li>
061 * <li>{@link org.springframework.messaging.MessageHeaders} arguments for obtaining
062 * access to all headers</li>
063 * <li>{@link org.springframework.messaging.support.MessageHeaderAccessor} or
064 * {@link org.springframework.jms.support.JmsMessageHeaderAccessor} for convenient
065 * access to all method arguments</li>
066 * </ul>
067 *
068 * <p>Annotated methods may have a non-{@code void} return type. When they do,
069 * the result of the method invocation is sent as a JMS reply to the destination
070 * defined by the {@code JMSReplyTO} header of the incoming message. If this header
071 * is not set, a default destination can be provided by adding
072 * {@link org.springframework.messaging.handler.annotation.SendTo @SendTo} to the
073 * method declaration.
074 *
075 * <p>This annotation may be used as a <em>meta-annotation</em> to create custom
076 * <em>composed annotations</em> with attribute overrides.
077 *
078 * @author Stephane Nicoll
079 * @since 4.1
080 * @see EnableJms
081 * @see JmsListenerAnnotationBeanPostProcessor
082 * @see JmsListeners
083 */
084@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
085@Retention(RetentionPolicy.RUNTIME)
086@Documented
087@Repeatable(JmsListeners.class)
088@MessageMapping
089public @interface JmsListener {
090
091        /**
092         * The unique identifier of the container managing this endpoint.
093         * <p>If none is specified, an auto-generated one is provided.
094         * @see org.springframework.jms.config.JmsListenerEndpointRegistry#getListenerContainer(String)
095         */
096        String id() default "";
097
098        /**
099         * The bean name of the {@link org.springframework.jms.config.JmsListenerContainerFactory}
100         * to use to create the message listener container responsible for serving this endpoint.
101         * <p>If not specified, the default container factory is used, if any.
102         */
103        String containerFactory() default "";
104
105        /**
106         * The destination name for this listener, resolved through the container-wide
107         * {@link org.springframework.jms.support.destination.DestinationResolver} strategy.
108         */
109        String destination();
110
111        /**
112         * The name for the durable subscription, if any.
113         */
114        String subscription() default "";
115
116        /**
117         * The JMS message selector expression, if any.
118         * <p>See the JMS specification for a detailed definition of selector expressions.
119         */
120        String selector() default "";
121
122        /**
123         * The concurrency limits for the listener, if any. Overrides the value defined
124         * by the container factory used to create the listener container.
125         * <p>The concurrency limits can be a "lower-upper" String &mdash; for example,
126         * "5-10" &mdash; or a simple upper limit String &mdash; for example, "10", in
127         * which case the lower limit will be 1.
128         * <p>Note that the underlying container may or may not support all features.
129         * For instance, it may not be able to scale, in which case only the upper limit
130         * is used.
131         */
132        String concurrency() default "";
133
134}