Метод не вызывается при использовании пространства имен Spring JMS - PullRequest
2 голосов
/ 16 марта 2011

У меня есть приложение, которое построено на Spring 3.0.5 и использует JMS для обмена сообщениями.Компоненты, которые получают сообщения, конфигурируются с использованием пространства имен jms.Класс выглядит следующим образом

class MyService {
    public void receive(String msg) {
        ...
    }
}

Конфигурация Spring выглядит следующим образом

<jms:listener-container destination-type="queue">
  <jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>

Однако, когда я изменяю метод приема, чтобы получить объект Message, метод больше не вызывается.

class MyService {
    public void receive(TextMessage msg) {
        ...
    }
}

Я понимаю, что могу просто использовать MessageListenerAdapter, но это больше затрат на настройку, и мне просто интересно, почему это не работает.

Любое понимание очень ценится.

Фрэнк

Ответы [ 2 ]

3 голосов
/ 16 марта 2011

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

Код в AbstractListenerContainerParser проверяет, не установлен ли атрибут message-converter в <jms:listener-container> или указывает на допустимый компонент. В противном случае создается экземпляр SimpleMessageAdapter.

Чтобы обойти эту проблему, я создал NoopMessageConverter, который решает проблему

public class NoopMessageConverter implements MessageConverter {
    @Override
    public Message toMessage(Object object, Session session) 
        throws JMSException, MessageConversionException {
        return (Message) object;
    }

    @Override
    public Object fromMessage(Message message) 
        throws JMSException, MessageConversionException {
        return message;
    }
}

Затем настройте <jms:listener-container> следующим образом

<bean id="noopMessageConverter" class="NoopMessageConverter"/>

<jms:listener-container message-converter="noopMessageConverter">
    <jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>

Затем вы можете создать свой боб следующим образом, и метод receive называется

class MyService {
    public void receive(TextMessage msg) {
        ...
    }
}
3 голосов
/ 16 марта 2011

Конфигурация <jms:listener> автоматически создает MessageListenerAdapter для вас, поэтому вам не нужно настраивать это явно.

Ваша проблема в том, что MessageListenerAdapter предназначен для отделения вашего кода от JMSAPI в целом.Целевой метод в <jms:listener> должен объявить один из типов параметров, разрешенных MessageListenerAdapter (см. документы ), которые представляют возможные типы полезной нагрузки сообщения, то есть один из String, Serializable, byte[] или Map.

Если вы хотите получить необработанный объект JMS TextMessage, тогда ваш класс слушателя должен реализовать MessageListener или SessionAwareMessageListener.Это делает его «правильным» слушателем JMS.В этом случае конфигурация method становится избыточной, и вы можете просто использовать:

<jms:listener destination="queue.test" ref="myService"/>

Я на самом деле довольно удивлен, что Spring не выдал исключение, когда обнаружил, что ваш метод receiveимел недопустимый тип параметра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...