Better hide lazy resolution of JMS payloads

This commit fixes MessagingMessageConverter to no longer expose the lazy
message resolution algorithm. This restores proper behaviour for
converters used outside of that context.

Instead, such arrangement is now private to
AbstractAdaptableMessageListener (as it should).

Issue: SPR-14389
This commit is contained in:
Stephane Nicoll
2016-06-29 18:10:34 +02:00
parent 2d5496df2b
commit eba873067c
5 changed files with 118 additions and 64 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 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.
@@ -35,6 +35,7 @@ import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.listener.SessionAwareMessageListener;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessagingMessageConverter;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
@@ -65,10 +66,21 @@ public class JmsListenerContainerFactoryIntegrationTests {
@Test
public void messageConverterUsedIfSet() throws JMSException {
containerFactory.setMessageConverter(new UpperCaseMessageConverter());
this.containerFactory.setMessageConverter(new UpperCaseMessageConverter());
testMessageConverterIsUsed();
}
@Test
public void messagingMessageConverterCanBeUsed() throws JMSException {
MessagingMessageConverter converter = new MessagingMessageConverter();
converter.setPayloadConverter(new UpperCaseMessageConverter());
this.containerFactory.setMessageConverter(converter);
testMessageConverterIsUsed();
}
private void testMessageConverterIsUsed() throws JMSException {
MethodJmsListenerEndpoint endpoint = createDefaultMethodJmsEndpoint(
listener.getClass(), "handleIt", String.class, String.class);
this.listener.getClass(), "handleIt", String.class, String.class);
Message message = new StubTextMessage("foo-bar");
message.setStringProperty("my-header", "my-value");

View File

@@ -29,7 +29,9 @@ import javax.jms.Topic;
import com.fasterxml.jackson.annotation.JsonView;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.jms.StubTextMessage;
@@ -51,6 +53,9 @@ import static org.mockito.BDDMockito.*;
*/
public class MessagingMessageListenerAdapterTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
private static final Destination sharedReplyDestination = mock(Destination.class);
private final DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
@@ -122,6 +127,31 @@ public class MessagingMessageListenerAdapterTests {
}
}
@Test
public void payloadConversionLazilyInvoked() throws JMSException {
javax.jms.Message jmsMessage = mock(javax.jms.Message.class);
MessageConverter messageConverter = mock(MessageConverter.class);
given(messageConverter.fromMessage(jmsMessage)).willReturn("FooBar");
MessagingMessageListenerAdapter listener = getSimpleInstance("simple", Message.class);
listener.setMessageConverter(messageConverter);
Message<?> message = listener.toMessagingMessage(jmsMessage);
verify(messageConverter, never()).fromMessage(jmsMessage);
assertEquals("FooBar", message.getPayload());
verify(messageConverter, times(1)).fromMessage(jmsMessage);
}
@Test
public void headerConversionLazilyInvoked() throws JMSException {
javax.jms.Message jmsMessage = mock(javax.jms.Message.class);
when(jmsMessage.getPropertyNames()).thenThrow(new IllegalArgumentException("Header failure"));
MessagingMessageListenerAdapter listener = getSimpleInstance("simple", Message.class);
Message<?> message = listener.toMessagingMessage(jmsMessage);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Header failure");
message.getHeaders(); // Triggers headers resolution
}
@Test
public void incomingMessageUsesMessageConverter() throws JMSException {
javax.jms.Message jmsMessage = mock(javax.jms.Message.class);

View File

@@ -74,30 +74,6 @@ public class MessagingMessageConverterTests {
assertEquals(1224L, msg.getPayload());
}
@Test
public void payloadConversionLazilyInvoked() throws JMSException {
TextMessage jmsMsg = new StubTextMessage("1224");
TestMessageConverter converter = new TestMessageConverter();
this.converter.setPayloadConverter(converter);
Message<?> msg = (Message<?>) this.converter.fromMessage(jmsMsg);
assertEquals("Converter should not have been called yet", false, converter.called);
assertEquals(1224L, msg.getPayload());
assertEquals("Converter should have been called", true, converter.called);
}
@Test
public void headerConversionLazilyInvoked() throws JMSException {
javax.jms.Message jmsMsg = mock(javax.jms.Message.class);
when(jmsMsg.getPropertyNames()).thenThrow(new IllegalArgumentException("Header failure"));
Message<?> msg = (Message<?>) this.converter.fromMessage(jmsMsg);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Header failure");
msg.getHeaders(); // Triggers headers resolution
}
static class TestMessageConverter extends SimpleMessageConverter {
private boolean called;