Spring Boot: чтение свойства spring.jms.jndi-name из файла application.properties с использованием класса Java Bean

Я использую поиск JNDI для получения объекта подключения для Websphere MQ Broker на сервере tomcat. Я использую JmsTemplate для отправки сообщений в очередь на WMQ Broker и пытаюсь избежать конфигурации на основе Spring Xml, и по этой причине я настроил файл Spring boot application.properties, чтобы указать JNDI ищу имя. Ниже - свойство из файла application.properties.

spring.jms.jndi-name= java:comp/env/XXXX

Я использую компонент Spring для определения JmsTemplate, и ниже приведен его код.

@Configuration
public class JmsMessageTemplateBean {

    //@Value("${spring.jms.jndi-name}")
    //private ConnectionFactory connectionFactory;

    @Bean
    public JmsTemplate jmsTemplate() throws Exception{
        JmsTemplate jmsMessagingTemplate = new JmsTemplate();
        jmsMessagingTemplate.setDefaultDestinationName("Some Queue");
        jmsMessagingTemplate.setConnectionFactory(connectionFactory);
        return jmsMessagingTemplate;
    }
}

у меня есть пара вопросов:

1. Как прочитать свойство JNDI из файла application.properties и установить для объекта Connection значение Jms Template в указанном выше bean-компоненте.

2. Я заметил, что объект подключения из поиска JNDI - это MQQueueConnectionFactory, а из того, что я исследовал, JmsTemplate поддерживает объект javax.jms.ConnectionFactory. есть ли способ преобразовать объект MQQueueConnectionfactory в javax.jms.Connectionfactory.

Оцените ваши ответы.


person maram05    schedule 18.07.2015    source источник
comment
Вы усложняете задачу. Удалите свой bean-компонент, у вас уже есть JmsTemplate с автоматической конфигурацией Spring Boots. MQQueueConnectionFactory - это ConnectionFactory.   -  person M. Deinum    schedule 18.07.2015
comment
@ M. Deinum Спасибо за ваш ответ. С конфигурацией автоматической загрузки Spring я получил JmsTemplate, но фабрика соединений по умолчанию смотрит на брокера localhost. Как я могу настроить JmsTemplate для использования имени spring.jms.jndi, указанного в файле application.properties.   -  person maram05    schedule 18.07.2015
comment
Если вы действительно указали это свойство, которое следует использовать для поиска. Также убедитесь, что в вашем пути к классу нет чего-то вроде activemq. Вы должны использовать Spring Boot 1.2 или выше, чтобы это работало.   -  person M. Deinum    schedule 19.07.2015


Ответы (1)


Мне также было сложно понять, как реализовать Spring Boot JMS Listener, прослушивая очередь ActiveMQ на сервере приложений JBoss.

ActiveMQ поддерживается автоконфигурацией Spring Boot, но поскольку он находился внутри сервера JBoss, Spring Boot не смог подключить ActiveMQ. Фактически, вам нужно определить bean-компоненты connectionFactory и jmsListenerContainerFactory самостоятельно, выполнив поиск в провайдере JNDI.

@Configuration
@EnableJms
public class ActiveMqConnectionFactoryConfig {

  @Value("${broker.url}")
  String brokerUrl;

  @Value("${borker.username}")
  String userName;

  @Value("${borker.password}")
  String password;

  @Value("${queue}")
  String queueName;

  private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
  private static final String CONNECTION_FACTORY = "jms/RemoteConnectionFactory";


  @Bean
  public ConnectionFactory connectionFactory() {
    try {
      System.out.println("Retrieving JMS queue with JNDI name: " + CONNECTION_FACTORY);
      JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
      jndiObjectFactoryBean.setJndiName(CONNECTION_FACTORY);

      jndiObjectFactoryBean.setJndiEnvironment(getEnvProperties());
      jndiObjectFactoryBean.afterPropertiesSet();

      return (QueueConnectionFactory) jndiObjectFactoryBean.getObject();

    } catch (NamingException e) {
      System.out.println("Error while retrieving JMS queue with JNDI name: [" + CONNECTION_FACTORY + "]");
    } catch (Exception ex) {
      System.out.println("Error");
    }
    return null;
  }

  Properties getEnvProperties() {
    Properties env = new Properties();
    env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
    env.put(Context.PROVIDER_URL, brokerUrl);
    env.put(Context.SECURITY_PRINCIPAL, userName);
    env.put(Context.SECURITY_CREDENTIALS, password);
    return env;
  }

  @Bean
  public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {

    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    JndiDestinationResolver jndiDestinationResolver = new JndiDestinationResolver();

    jndiDestinationResolver.setJndiEnvironment(getEnvProperties());
    factory.setDestinationResolver(jndiDestinationResolver);
    return factory;
  }

Затем, если вы хотите использовать очередь, вы просто определяете свой класс потребителя JMS с помощью метода, аннотированного @JmsListener(destination = "${queue}")

 @JmsListener(destination = "${queue}")
  public void receive(Message message) {
    System.out.println("Received Message: " + message);
  }

Надеюсь, что это поможет сэкономить несколько часов исследований;) Ура

person Thomas Joeisseint    schedule 19.11.2018
comment
Это очень подробный ответ, но вопрос касался IBM Websphere MQ, а ответ, который вы предоставили, касается ActiveMQ, я не уверен, что базовая информация о конфигурации, которую вы предоставили для ActiveMQ, поможет кому-то в решении проблемы для IBM MQ, если так что им, возможно, стоит оставить этот вопрос. Если нет, то, вероятно, лучше найти вопрос, связанный с ActiveMQ, чтобы дать этот ответ, или даже задать свой вопрос и ответить на него самостоятельно. - person JoshMc; 19.11.2018
comment
Спасибо, Джош, да, ты прав, мне лучше создать новый вопрос и ответить на него. Я опубликовал этот вопрос, потому что он больше всего связан с проблемами реализации, с которыми я столкнулся, но все еще существует значительный разрыв между исходным вопросом и моим ответом :) - person Thomas Joeisseint; 22.11.2018
comment
@ThomasJoeisseint Я пытаюсь подключить activemq к серверу JBOSS. Но я получаю ошибку ниже, вызванную: java.lang.IllegalArgumentException: свойство 'connectionFactory' требуется в org.springframework.jms.support.JmsAccessor.afterPropertiesSet (JmsAccessor.java:169) - person Gopi; 24.01.2020