Spring JmsTemplate и поиск соединения jndi на сервере приложений WebSphere

Я работаю над отправкой и получением сообщений в/из очереди IBM MQ, используя JmsTemplate. Мое приложение установлено на сервере приложений WebSphere 8.5, и для получения соединения я использую поиск jndi.

Мои весенние бобы:

<bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiName" value="jndiTest" /> 
    <property name="lookupOnStartup" value="false" /> 
    <property name="cache" value="true" /> 
    <property name="proxyInterface" value="javax.jms.QueueConnectionFactory" /> 
</bean> 

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsQueueConnectionFactory" />
    <property name="receiveTimeout" value="10000" /> 
    <property name="sessionAcknowledgeMode" value="1" /> 
</bean>

<bean id="mqServerDao" class="MqServerDao" > 
    <constructor-arg name="jmsTemplate" ref="jmsTemplate" />
</bean>

Мой класс Java:

public class MqServerDao {

    private JmsTemplate jmsTemplate;

    public MqServerDao(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    public String write(byte[] request, final String correlationId)
                                   throws Exception {

       MQQueue mqQueue = new MQQueue(MQ_INPUT_QUEUE);
       mqQueue.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);

       MqRequestMessageCreator messageCreator = new MqRequestMessageCreator(
                                       request, correlationId);
       jmsTemplate.send(mqQueue, messageCreator);
       return messageCreator.getMessageId();
    }

    public byte[] read(String messageId, String correlationId) throws Exception {

       MQQueue mqQueue = new MQQueue(MQ_OUTPUT_QUEUE);
       mqQueue.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);

       String messageSelector = "JMSCorrelationID = 'ID:" + correlationId
                                       + "' AND JMSMessageID = '" + messageId + "'";
       TextMessage receiveMessage = (TextMessage) jmsTemplate.receiveSelected(
                                       mqQueue, messageSelector);
       return receiveMessage.getText().getBytes();
    }
}

Интересно, это правильный способ сделать это, и у меня есть несколько вопросов:

  1. Рекомендуется ли добавлять CachingConnectionFactory или сам сервер приложений управляет соединениями?
  2. Это правильный способ использования JmsTemplate? Безопасно ли, если метод «записи» MqServerDao вызывается дважды одновременно? Или я должен создать новый экземпляр JmsTemplate внутри методов «записи» и «чтения»?

person Teo    schedule 13.07.2016    source источник


Ответы (1)


  1. WebSphere будет управлять соединениями вместо вас. Из http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/core/JmsTemplate.html:

В среде Java EE убедитесь, что ConnectionFactory получен из контекста именования среды приложения через JNDI; серверы приложений обычно предоставляют там объединенные фабрики с поддержкой транзакций.

  1. Классы шаблонов Spring, в том числе JmsTemplate, предназначены для повторного использования, потокобезопасных синглетонов. Вы определенно не хотите продолжать создавать новые.

Я искал авторитетную ссылку на это, но не смог найти. (Вы могли бы подумать, что это будет в приведенной выше ссылке JavaDoc. IMO, документация Spring часто оставляет желать лучшего.) Лучшее, что я смог найти до сих пор, это это описание RestTemplate, в котором говорится:

Концептуально он очень похож на JdbcTemplate, JmsTemplate и различные другие шаблоны, используемые в Spring Framework и других портфельных проектах. Это означает, например, что RestTemplate является потокобезопасным после создания и что вы можете использовать обратные вызовы для настройки его операций.

person dbreaux    schedule 15.07.2016