首先Spring提供了多種connectionFactory,SingleConnectionFactory是其中的一種實現SingleConnectionFactory對於建立JMS服務器鏈接的請求會一直返回同一個鏈接,並且會忽略Connection的close方法調用。而CachingConnectionFactory繼承了SingleConnectionFactory,它擁有SingleConnectionFactory的所有功能,同時它還新增了緩存功能,它可以緩存Session、MessageProducer和MessageConsumer。
1.1 首先需要在配置文件中注入CachingConnectionFactory
<beanid="connectionFactory"class="org.springframework.jms.connection.CachingConnectionFactory">
</bean>
1.2、Spring提供的ConnectionFactory只是用於管理。真正需要連接到jms服務上的還需要jms的開發方在提供。如何配置ActiveMQ提供的ConnectionFactory?
<!-- ActiveMQ 連接工廠 -->
<amq:connectionFactoryid="amqConnectionFactory"
brokerURL="tcp://127.0.0.1:61616"userName="admin"password="admin" />
<!-- SpringCaching連接工廠 -->
<!-- Spring用於管理真正的ConnectionFactory的ConnectionFactory -->
<beanid="connectionFactory"class="org.springframework.jms.connection.CachingConnectionFactory">
<!-- 目標ConnectionFactory對應真實的可以產生JMS Connection的ConnectionFactory -->
<propertyname="targetConnectionFactory"ref="amqConnectionFactory"></property>
<!-- Session緩存數量 -->
<propertyname="sessionCacheSize"value="100" />
</bean>
1.3、配置生產者
生產者負責產生消息併發送到JMS服務器。在Spring中提供JmsTemplate類來實現。用JmsTemplate進行消息發送的時候需要告訴程序發送的那種類型,點對點還是,發佈訂閱?配置如下:
<!-- 定義JmsTemplate的Queue類型 -->
<beanid="jmsQueueTemplate"class="org.springframework.jms.core.JmsTemplate">
<constructor-argref="connectionFactory" />
<!--隊列模式 -->
<propertyname="pubSubDomain"value="false" />
</bean>
<!-- 定義JmsTemplate的Topic類型 -->
<beanid="jmsTopicTemplate"class="org.springframework.jms.core.JmsTemplate">
<!-- 這個connectionFactory對應的是我們定義的Spring提供的那個ConnectionFactory對象 -->
<constructor-argref="connectionFactory" />
<!-- pub/sub模型(發佈/訂閱) -->
<propertyname="pubSubDomain"value="true" />
</bean>
1.4、配置消費者
消費者是對指定目的地的消息進行消費,每個消費者對應每個目的地都需要有對應的MessageListenerContainer。對於消息監聽容器而言,除了要知道監聽哪個目的地之外,還需要知道到哪裏去監聽,也就是說它還需要知道去監聽哪個JMS服務器,通過配置MessageListenerContainer的時候往裏面注入一個ConnectionFactory來實現的。所以我們在配置一個MessageListenerContainer的時候有三個屬性必須指定:一個是表示從哪裏監聽的ConnectionFactory;一個是表示監聽什麼的Destination;一個是接收到消息以後進行消息處理的MessageListener。
<!-- 定義Queue監聽器點對點隊列 -->
<jms:listener-containerdestination-type="queue"container-type="default"connection-factory="connectionFactory"acknowledge="auto">
<jms:listenerdestination="test.queue"ref="queueReceiver1"/>
<jms:listenerdestination="test.queue"ref="queueReceiver2"/>
</jms:listener-container>
<!-- 定義Topic監聽器訂閱-->
<jms:listener-containerdestination-type="topic"container-type="default"connection-factory="connectionFactory"acknowledge="auto">
<jms:listenerdestination="test.topic"ref="topicReceiver1"/>
<jms:listenerdestination="test.topic"ref="topicReceiver2"/>
</jms:listener-container>
代碼實現一對一的生產和消費
生產者:
@Autowired
@Qualifier("jmsQueueTemplate")
private JmsTemplate jmsTemplate;
/**
* 發送一條消息到指定的隊列(目標)
* @paramqueueName隊列名稱
* @param message消息內容
*/
public void send(String queueName,final String message){
jmsTemplate.send(queueName, new MessageCreator() {
@Override
public MessagecreateMessage(Session session) throwsJMSException {
return session.createTextMessage(message);
}
});
}
接受者:
@Component
publicclasQueueReceiver1 implements MessageListener {
public voidrecMessage(Message message){
try {
System.out.println("Receiver1接收到消息:"+((TextMessage)message).getText());
}catch(JMSException e) {
e.printStackTrace();
}
}
}
訂閱與發佈
發佈者:
@Component("topicSender")
public classTopicSender {
@Autowired
@Qualifier("jmsTopicTemplate")
private JmsTemplate jmsTemplate;
/**
* 發送一條消息到指定的隊列(目標)
* @param queueName 隊列名稱
* @param message 消息內容
*/
public void send(String topicName,final String message){
jmsTemplate.send(topicName, new MessageCreator() {
@Override
public MessagecreateMessage(Session session) throwsJMSException {
return session.createTextMessage(message);
}
});
}
}
訂閱者:
@Component
public classTopicReceiver1 implements MessageListener{
@Override
public void onMessage(Message message) {
try {
System.out.println("TopicReceiver1接收到消息:"+((TextMessage)message).getText());
}catch(JMSException e) {
e.printStackTrace();
}
}
}