Auto-configure JMS MessageConverter
If a `MessageConverter` bean is available, we now associate it to the created `JmsTemplate` and `JmsListenerContainerFactory`. That way, registering a custom `MessageConverter` is all that's needed. The JMS auto-configuration is now using the new `ObjectProvider` that offers a nicer API to detect if a primary candidate is available for optional collaborators. Closes gh-4282
This commit is contained in:
parent
ad7cf48497
commit
d13b9a98c5
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.jms;
|
|||
import javax.jms.ConnectionFactory;
|
||||
|
||||
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
import org.springframework.jms.support.destination.DestinationResolver;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
import org.springframework.util.Assert;
|
||||
|
|
@ -33,6 +34,8 @@ public final class DefaultJmsListenerContainerFactoryConfigurer {
|
|||
|
||||
private DestinationResolver destinationResolver;
|
||||
|
||||
private MessageConverter messageConverter;
|
||||
|
||||
private JtaTransactionManager transactionManager;
|
||||
|
||||
private JmsProperties jmsProperties;
|
||||
|
|
@ -46,6 +49,16 @@ public final class DefaultJmsListenerContainerFactoryConfigurer {
|
|||
this.destinationResolver = destinationResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link MessageConverter} to use or {@code null} if the out-of-the-box
|
||||
* converter should be used.
|
||||
* @param messageConverter the {@link MessageConverter}
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public void setMessageConverter(MessageConverter messageConverter) {
|
||||
this.messageConverter = messageConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link JtaTransactionManager} to use or {@code null} if the JTA support
|
||||
* should not be used.
|
||||
|
|
@ -84,6 +97,9 @@ public final class DefaultJmsListenerContainerFactoryConfigurer {
|
|||
if (this.destinationResolver != null) {
|
||||
factory.setDestinationResolver(this.destinationResolver);
|
||||
}
|
||||
if (this.messageConverter != null) {
|
||||
factory.setMessageConverter(this.messageConverter);
|
||||
}
|
||||
JmsProperties.Listener listener = this.jmsProperties.getListener();
|
||||
factory.setAutoStartup(listener.isAutoStartup());
|
||||
if (listener.getAcknowledgeMode() != null) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.jms;
|
|||
|
||||
import javax.jms.ConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnJndi;
|
||||
|
|
@ -27,6 +28,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
import org.springframework.jms.annotation.EnableJms;
|
||||
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
|
||||
import org.springframework.jms.config.JmsListenerConfigUtils;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
import org.springframework.jms.support.destination.DestinationResolver;
|
||||
import org.springframework.jms.support.destination.JndiDestinationResolver;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
|
@ -42,11 +44,14 @@ import org.springframework.transaction.jta.JtaTransactionManager;
|
|||
@ConditionalOnClass(EnableJms.class)
|
||||
class JmsAnnotationDrivenConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private DestinationResolver destinationResolver;
|
||||
@Autowired
|
||||
private ObjectProvider<DestinationResolver> destinationResolver;
|
||||
|
||||
@Autowired(required = false)
|
||||
private JtaTransactionManager transactionManager;
|
||||
@Autowired
|
||||
private ObjectProvider<JtaTransactionManager> transactionManager;
|
||||
|
||||
@Autowired
|
||||
private ObjectProvider<MessageConverter> messageConverter;
|
||||
|
||||
@Autowired
|
||||
private JmsProperties properties;
|
||||
|
|
@ -55,8 +60,9 @@ class JmsAnnotationDrivenConfiguration {
|
|||
@ConditionalOnMissingBean
|
||||
public DefaultJmsListenerContainerFactoryConfigurer jmsListenerContainerFactoryConfigurer() {
|
||||
DefaultJmsListenerContainerFactoryConfigurer configurer = new DefaultJmsListenerContainerFactoryConfigurer();
|
||||
configurer.setDestinationResolver(this.destinationResolver);
|
||||
configurer.setTransactionManager(this.transactionManager);
|
||||
configurer.setDestinationResolver(this.destinationResolver.getIfUnique());
|
||||
configurer.setTransactionManager(this.transactionManager.getIfUnique());
|
||||
configurer.setMessageConverter(this.messageConverter.getIfUnique());
|
||||
configurer.setJmsProperties(this.properties);
|
||||
return configurer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
* Copyright 2012-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.
|
||||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.jms;
|
|||
|
||||
import javax.jms.ConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
|
|
@ -29,6 +30,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.jms.core.JmsMessagingTemplate;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
import org.springframework.jms.support.destination.DestinationResolver;
|
||||
|
||||
/**
|
||||
|
|
@ -50,8 +52,11 @@ public class JmsAutoConfiguration {
|
|||
@Autowired
|
||||
private ConnectionFactory connectionFactory;
|
||||
|
||||
@Autowired(required = false)
|
||||
private DestinationResolver destinationResolver;
|
||||
@Autowired
|
||||
private ObjectProvider<DestinationResolver> destinationResolver;
|
||||
|
||||
@Autowired
|
||||
private ObjectProvider<MessageConverter> messageConverter;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
|
|
@ -59,7 +64,10 @@ public class JmsAutoConfiguration {
|
|||
JmsTemplate jmsTemplate = new JmsTemplate(this.connectionFactory);
|
||||
jmsTemplate.setPubSubDomain(this.properties.isPubSubDomain());
|
||||
if (this.destinationResolver != null) {
|
||||
jmsTemplate.setDestinationResolver(this.destinationResolver);
|
||||
jmsTemplate.setDestinationResolver(this.destinationResolver.getIfUnique());
|
||||
}
|
||||
if (this.messageConverter != null) {
|
||||
jmsTemplate.setMessageConverter(this.messageConverter.getIfUnique());
|
||||
}
|
||||
return jmsTemplate;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.springframework.boot.test.EnvironmentTestUtils;
|
|||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.jms.annotation.EnableJms;
|
||||
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
|
||||
|
|
@ -42,6 +43,7 @@ import org.springframework.jms.config.SimpleJmsListenerContainerFactory;
|
|||
import org.springframework.jms.core.JmsMessagingTemplate;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.listener.DefaultMessageListenerContainer;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
@ -202,6 +204,20 @@ public class JmsAutoConfigurationTests {
|
|||
.getPropertyValue("transactionManager")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultContainerFactoryWithMessageConverters() {
|
||||
this.context = createContext(MessageConvertersConfiguration.class,
|
||||
EnableJmsConfiguration.class);
|
||||
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
|
||||
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
|
||||
assertThat(jmsListenerContainerFactory.getClass())
|
||||
.isEqualTo(DefaultJmsListenerContainerFactory.class);
|
||||
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory) jmsListenerContainerFactory)
|
||||
.createListenerContainer(mock(JmsListenerEndpoint.class));
|
||||
assertThat(listenerContainer.getMessageConverter())
|
||||
.isSameAs(this.context.getBean("myMessageConverter"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomContainerFactoryWithConfigurer() {
|
||||
this.context = doLoad(
|
||||
|
|
@ -219,6 +235,15 @@ public class JmsAutoConfigurationTests {
|
|||
assertThat(listenerContainer.isAutoStartup()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testJmsTemplateWithMessageConverters() {
|
||||
load(MessageConvertersConfiguration.class);
|
||||
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
|
||||
assertThat(jmsTemplate.getMessageConverter()).isSameAs(
|
||||
this.context.getBean("myMessageConverter"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPubSubDisabledByDefault() {
|
||||
load(TestConfiguration.class);
|
||||
|
|
@ -452,6 +477,22 @@ public class JmsAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class MessageConvertersConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public MessageConverter myMessageConverter() {
|
||||
return mock(MessageConverter.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageConverter anotherMessageConverter() {
|
||||
return mock(MessageConverter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration9 {
|
||||
|
||||
|
|
|
|||
|
|
@ -3590,7 +3590,9 @@ beans:
|
|||
----
|
||||
|
||||
NOTE: {spring-javadoc}/jms/core/JmsMessagingTemplate.{dc-ext}[`JmsMessagingTemplate`]
|
||||
can be injected in a similar manner.
|
||||
can be injected in a similar manner. If a `DestinationResolver` or `MessageConverter`
|
||||
beans are defined, they are associated automatically to the auto-configured
|
||||
`JmsTemplate`.
|
||||
|
||||
|
||||
|
||||
|
|
@ -3599,7 +3601,8 @@ can be injected in a similar manner.
|
|||
|
||||
When the JMS infrastructure is present, any bean can be annotated with `@JmsListener` to
|
||||
create a listener endpoint. If no `JmsListenerContainerFactory` has been defined, a
|
||||
default one is configured automatically.
|
||||
default one is configured automatically. If a `DestinationResolver` or `MessageConverter`
|
||||
beans are defined, they are associated automatically to the default factory.
|
||||
|
||||
The default factory is transactional by default. If you are running in an infrastructure
|
||||
where a `JtaTransactionManager` is present, it will be associated to the listener container
|
||||
|
|
|
|||
Loading…
Reference in New Issue