Spring 4.1 Конфигурация @JmsListener
Я хотел бы использовать новые аннотации и функции, представленные в Spring 4.1 для приложения, которое нуждается в прослушивании JMS.
Я внимательно прочитал примечания в сообщении Spring 4.1 JMS, но я продолжаю пропустить связь между @JmsListener
и возможно, DestinationResolver
и как настроить приложение, чтобы указать правильные Destination
или Endpoint
.
Вот рекомендуемое использование @JmsListener
@Component
public class MyService {
@JmsListener(containerFactory = "myContainerFactory", destination = "myQueue")
public void processOrder(String data) { ... }
}
Теперь я не могу использовать это в своем фактическом коде, потому что "myQueue" необходимо прочитать из файла конфигурации с помощью Environment.getProperty()
.
Я могу настроить соответствующий myContainerFactory с помощью DestinationResolver
, но в основном, кажется, вы просто используете DynamicDestinationResolver
, если вам не нужен JNDI для поиска очереди на сервере приложений, и вам не нужно было делать какие-либо пользовательские логика ответа. Я просто пытаюсь понять, как Spring хочет, чтобы я указывал имя очереди в параметризованной форме, используя аннотацию @JmsListener
.
Далее в блоге я найду ссылку на этот конфигуратор:
@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setDefaultContainerFactory(defaultContainerFactory());
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setDestination("anotherQueue");
endpoint.setMessageListener(message -> {
// processing
});
registrar.registerEndpoint(endpoint);
}
Теперь это имеет некоторое значение, и я мог видеть, где это позволит мне установить Destination во время выполнения из какой-либо внешней строки, но это, похоже, противоречит использованию @JmsListener
, поскольку оно, кажется, переопределяет аннотации в пользу endpoint.setMessageListener
в приведенном выше коде.
Любые советы о том, как указать подходящее имя очереди с помощью @JmsListener
?
Ответы
Ответ 1
В конечном итоге вы можете сделать это прямо сейчас, но это немного запутанно. Вы можете установить пользовательский JmsListenerEndpointRegistry
с помощью JmsListenerConfigurer
@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setEndpointRegistry(customRegistry());
}
}
а затем переопределить метод registerListenerContainer, что-то вроде
public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory) {
// resolve destination according to whatever -> resolvedDestination
((AbstractJmsListenerEndpoint)endpoint).setDestination(resolvedDestination);
super.registerListenerContainer(endpoint, factory);
}
Но мы могли бы сделать лучше. Пожалуйста, смотрите/голосуйте за SPR-12280
Ответ 2
Также обратите внимание, что в зависимости от варианта использования вы уже можете параметризовать использование файла свойств для среды и PropertySourcesPlaceholderConfigurer
@JmsListener(destinations = "${some.key}")
Согласно https://jira.spring.io/browse/SPR-12289
Ответ 3
Если люди используют @JmsListener
с загрузкой spring, вам не нужно настраивать PropertySourcesPlaceholderConfigurer
. Он выдает окно
Пример:
класс
@JmsListener(destination = "${spring.activemq.queue.name}")
public void receiveEntityMessage(final TextMessage message) {
// process stuff
}
}
application.properties
spring.activemq.queue.name=some.weird.queue.name.that.does.not.exist
Spring загрузочный вывод
[26-Aug;15:07:53.475]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection
[26-Aug;15:07:58.589]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist
[26-Aug;15:07:59.787]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection
[26-Aug;15:08:04.881]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist
Это доказывает, что @JmsListener может выбирать значения свойств из application.properties без фактической настройки явного PropertySourcesPlaceholderConfigurer
Надеюсь, это поможет!