JMS annotation-driven endpoints.
This commit adds the support of JMS annotated endpoint. Can be activated both by @EnableJms or <jms:annotation-driven/> and detects methods of managed beans annotated with @JmsListener, either directly or through a meta-annotation. Containers are created and managed under the cover by a registry at application startup time. Container creation is delegated to a JmsListenerContainerFactory that is identified by the containerFactory attribute of the JmsListener annotation. Containers can be retrieved from the registry using a custom id that can be specified directly on the annotation. A "factory-id" attribute is available on the container element of the XML namespace. When it is present, the configuration defined at the namespace level is used to build a JmsListenerContainerFactory that is exposed with the value of the "factory-id" attribute. This can be used as a smooth migration path for users having listener containers defined at the namespace level. It is also possible to migrate all listeners to annotated endpoints and yet keep the <jms:listener-container> or <jms:jca-listener-container> element to share the container configuration. The configuration can be fine-tuned by implementing the JmsListenerConfigurer interface which gives access to the registrar used to register endpoints. This includes a programmatic registration of endpoints in complement to the declarative approach. A default JmsListenerContainerFactory can also be specified to be used if no containerFactory has been set on the annotation. Annotated methods can have flexible method arguments that are similar to what @MessageMapping provides. In particular, jms listener endpoint methods can fully use the messaging abstraction, including convenient header accessors. It is also possible to inject the raw javax.jms.Message and the Session for more advanced use cases. The payload can be injected as long as the conversion service is able to convert it from the original type of the JMS payload. By default, a DefaultJmsHandlerMethodFactory is used but it can be configured further to support additional method arguments or to customize conversion and validation support. The return type of an annotated method can also be an instance of Spring's Message abstraction. Instead of just converting the payload, such response type allows to communicate standard and custom headers. The JmsHeaderMapper infrastructure from Spring integration has also been migrated to the Spring framework. SimpleJmsHeaderMapper is based on SI's DefaultJmsHeaderMapper. The simple implementation maps all JMS headers so that the generated Message abstraction has all the information stored in the protocol specific message. Issue: SPR-9882
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.messaging.converter;
|
||||
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An extension of the {@link SimpleMessageConverter} that uses a
|
||||
* {@link ConversionService} to convert the payload of the message
|
||||
* to the requested type.
|
||||
*
|
||||
* <p>Return {@code null} if the conversion service cannot convert
|
||||
* from the payload type to the requested type.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @see ConversionService
|
||||
*/
|
||||
public class GenericMessageConverter extends SimpleMessageConverter {
|
||||
|
||||
private final ConversionService conversionService;
|
||||
|
||||
/**
|
||||
* Create a new instance with the {@link ConversionService} to use.
|
||||
*/
|
||||
public GenericMessageConverter(ConversionService conversionService) {
|
||||
Assert.notNull(conversionService, "ConversionService must not be null");
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fromMessage(Message<?> message, Class<?> targetClass) {
|
||||
Object payload = message.getPayload();
|
||||
if (conversionService.canConvert(payload.getClass(), targetClass)) {
|
||||
try {
|
||||
return conversionService.convert(payload, targetClass);
|
||||
}
|
||||
catch (ConversionException e) {
|
||||
throw new MessageConversionException(message, "Failed to convert message payload '"
|
||||
+ payload + "' to '" + targetClass.getName() + "'", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* Invokes the handler method for a given message after resolving
|
||||
* its method argument values through registered {@link HandlerMethodArgumentResolver}s.
|
||||
*
|
||||
* <p>Use {@link #setMessageMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)}
|
||||
* <p>Use {@link #setMessageMethodArgumentResolvers(HandlerMethodArgumentResolver)}
|
||||
* to customize the list of argument resolvers.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -40,7 +40,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
*/
|
||||
public class InvocableHandlerMethod extends HandlerMethod {
|
||||
|
||||
private HandlerMethodArgumentResolverComposite argumentResolvers = new HandlerMethodArgumentResolverComposite();
|
||||
private HandlerMethodArgumentResolver argumentResolvers = new HandlerMethodArgumentResolverComposite();
|
||||
|
||||
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
@@ -74,7 +74,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
/**
|
||||
* Set {@link HandlerMethodArgumentResolver}s to use to use for resolving method argument values.
|
||||
*/
|
||||
public void setMessageMethodArgumentResolvers(HandlerMethodArgumentResolverComposite argumentResolvers) {
|
||||
public void setMessageMethodArgumentResolvers(HandlerMethodArgumentResolver argumentResolvers) {
|
||||
this.argumentResolvers = argumentResolvers;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.messaging.mapping;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* Generic strategy interface for mapping {@link MessageHeaders} to and from other
|
||||
* types of objects. This would typically be used by adapters where the "other type"
|
||||
* has a concept of headers or properties (HTTP, JMS, AMQP, etc).
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @param <T> type of the instance to and from which headers will be mapped.
|
||||
*/
|
||||
public interface HeaderMapper<T> {
|
||||
|
||||
void fromHeaders(MessageHeaders headers, T target);
|
||||
|
||||
Map<String, Object> toHeaders(T source);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes related to mapping to/from message headers.
|
||||
*/
|
||||
package org.springframework.messaging.mapping;
|
||||
Reference in New Issue
Block a user