Spring JMS, определяющий несколько назначений

#java #spring #jms #jndi #spring-jms

#java #spring #jms #jndi #spring-jms

Вопрос:

В документации spring говорится:

Назначения, как экземпляры ConnectionFactory, являются объектами, управляемыми JMS, которые вы можете хранить и извлекать в JNDI. При настройке контекста приложения Spring вы можете использовать фабричный класс JNDI JndiObjectFactoryBean или для выполнения внедрения зависимостей в ссылки вашего объекта на назначения JMS.

Однако эта стратегия часто оказывается громоздкой, если в приложении имеется большое количество назначений или если существуют расширенные функции управления назначениями, уникальные для поставщика JMS.

Вопрос в том:

Как действовать, когда у меня в приложении большое количество назначений?

Используя стратегию, упомянутую выше, я должен определить:

  • JndiTemplate
  • JndiDestinationResolver
  • JndiObjectFactoryBean
  • CachingConnectionFactory
  • JmsTemplate

Для КАЖДОГО назначения.

Итак, если у меня будет 20 очередей, мне придется определить 100 таких компонентов…

Комментарии:

1. Вы можете лениво разрешить назначения, вам нужен только один JmsTemplate и ConnectionFactory (при условии, что все они используют один и тот же поставщик / экземпляр JMS). Все остальное можно лениво просмотреть, используя send(destination, message) методы на JmsTemplate .

Ответ №1:

В комментарии к документации Spring делается замечание о «использовании JNDI для конечных точек назначения» по сравнению с «не использованием JNDI для конечных точек назначения». Итак, в вашем случае — хранятся ли ваши назначения в JNDI? Если вам не нужно это использовать, забудьте об этом. Загружайте только свой ConnectionFactory (один объект) из JNDI или просто создайте его с нуля.

И тогда вам не нужно назначать по одному компоненту Spring для каждого назначения. У вас может быть только один Java ‘consumer bean’, который затем использует JmsTemplate. Я предполагаю, что ваша фабрика соединений такая же, так что это только одна new JmsTemplate(connectionFactory) . Затем выполните CreateSession / createConsumer и т.д. По мере необходимости.

Комментарии:

1. Проблема в том, что мои очереди определены в файлах JNDI, и они довольно большие. Спасибо за ответ.

Ответ №2:

Вы можете просто использовать один JmsTemplate , CachingConnectionFactory и JndiDestinationResolver

Весь смысл использования DestinationResolver заключается в том, чтобы лениво разрешить назначения для вас. Используйте конкретный send или [ convertAndSend][5]. The destininationName will be passed on to the DestinationResolver` для получения назначения.

Единственным недостатком является то, что вам нужно использовать jndi-name в качестве destinationName.

 
@Bean
public JndiDestinationResolver jndiDestinationResolver() {
  return new JndiDestinationResolver();
}

@Bean
public JmsTemplate jmsTemplate() {
  JmsTemplate jmsTemplate = new JmsTemplate();
  jmsTemplate.setDestinationResolver(jndiDestinationResolver());
  jmsTemplate.setConnectionFactory(connectionFactory());
  return jmsTemplate;
}
  

С помощью этого вы можете использовать следующее для динамического разрешения назначения из JNDI.

 
jmsTemplate.send("jms/queue1", "This is a message");
jmsTemplate.send("jms/queue3", "This is another message");