Я использую Spring JMS и использую аннотированный метод @JmsListener, который обрабатывает входящие сообщения, а также отвечает на них.
Проблема в том, что мне нужно установить режим доставки NON_PERSISTENT, а используемая библиотека IBM MQ по умолчанию - PERSISTENT, которую можно было изменить только при вызове (внутреннего) метода send.
В другом вопросе здесь, о stackoverflow, было упомянуто, что можно установить режим доставки JmsTemplate, но, к сожалению, шаблон не используется для аннотированного метода @JmsListener.
После отладки я обнаружил MessagingMessageListenerAdapter, у которого есть метод postProcessProducer, который я могу перезаписать, чтобы вручную изменить настройки созданного MessageProducer. К сожалению, довольно сложно расширить этот класс и позволить Spring использовать его. У меня все заработало, но я сомневаюсь, что это лучшее решение, и при его наличии режим доставки для всех моих методов @JmsListener будет установлен на NON_PERSISTENT (пока для меня это не проблема, но, возможно, в будущем):
// bean definition in my @Configuration class:
@Bean(name = JmsListenerConfigUtils.JMS_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public JmsListenerAnnotationBeanPostProcessor jmsListenerAnnotationProcessor() {
return new JmsListenerAnnotationBeanPostProcessor() {
@Override
protected MethodJmsListenerEndpoint createMethodJmsListenerEndpoint() {
return new MethodJmsListenerEndpoint() {
@Override
protected MessagingMessageListenerAdapter createMessageListenerInstance() {
return new MessagingMessageListenerAdapter() {
@Override
protected void postProcessProducer(MessageProducer producer, Message response)
throws JMSException {
super.postProcessProducer(producer, response);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
}
};
}
};
}
};
}
Есть ли более простой способ установить режим доставки, когда я использую @JmsListener? Я нашел много классов, где я могу установить режим доставки, но я не нашел никакого способа сделать это на одном из bean-компонентов, которые мне пришлось определить, чтобы запустить установку JMS (например, JmsListenerContainerFactory или ConnectionFactory).
Обновлено: К сожалению, мы используем Spring 4.x и не можем обновить до 5.x




В Spring 5 (в настоящее время 5.0.6) теперь вы можете установить объект QosSettings в свойстве документы здесь фабрики контейнеров responseQosSettings; прокрутите немного вниз.
Finally if you need to specify some QoS values for the response such as the priority or the time to live, you can configure the JmsListenerContainerFactory accordingly:
public class QosSettings {
private int deliveryMode;
private int priority;
private long timeToLive;
...
}
Если вы можете получить доступ к очереди, используя формат URI, посмотрите этот ответ, который я предоставил в другом сообщении SO: stackoverflow.com/questions/50333116/…
Спасибо @JoshMc, хорошая попытка, но, к сожалению, она не работает с моим вариантом использования. Мы используем CachedMessageProducer, который всегда вызывает send со значением persistence по умолчанию, которое по-прежнему равно 2 и, следовательно, не соответствует значению из URI.
Выглядит неплохо, но, к сожалению, мы используем Spring 4.x и не можем обновиться до 5.x (я не упомянул об этом). Есть ли какое-нибудь решение, совместимое с Spring 4?