若要直接使用JMS API來進行訊息傳送與接收,基本上都會有一些固定的流程,例如一個JMS傳送者可以如下撰寫:
// 處理例外
try {
// 設定系統屬性
System.setProperty("com.sun.appserv.iiop.endpoints", "127.0.0.1:3700");
// 設定 JNDI 屬性
Properties properties = new Properties();
properties.setProperty(Context.PROVIDER_URL, "iiop://127.0.0.1:3700");
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.appserv.naming.S1ASCtxFactory");
// 建立 Context
Context ctx = new InitialContext(properties);
// 查找 ConnectionFactory
ConnectionFactory connectionFactory =
(ConnectionFactory) ctx.lookup("jms/HelloQueueFactory");
// 查找 Destination
Queue queue = (Queue) ctx.lookup("jms/HelloQueue");
// 建立 Connection
Connection connection = connectionFactory.createConnection();
// 建立 Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 建立 MessageProducer
MessageProducer messageProducer = session.createProducer(queue);
// 建立訊息並傳送
for (int i = 0; i < 5; i++) {
TextMessage message = session.createTextMessage("Message " + ": " + i);
messageProducer.send(message);
}
} catch (Exception ex) {
ex.printStackTrace();
}
try {
// 設定系統屬性
System.setProperty("com.sun.appserv.iiop.endpoints", "127.0.0.1:3700");
// 設定 JNDI 屬性
Properties properties = new Properties();
properties.setProperty(Context.PROVIDER_URL, "iiop://127.0.0.1:3700");
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.appserv.naming.S1ASCtxFactory");
// 建立 Context
Context ctx = new InitialContext(properties);
// 查找 ConnectionFactory
ConnectionFactory connectionFactory =
(ConnectionFactory) ctx.lookup("jms/HelloQueueFactory");
// 查找 Destination
Queue queue = (Queue) ctx.lookup("jms/HelloQueue");
// 建立 Connection
Connection connection = connectionFactory.createConnection();
// 建立 Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 建立 MessageProducer
MessageProducer messageProducer = session.createProducer(queue);
// 建立訊息並傳送
for (int i = 0; i < 5; i++) {
TextMessage message = session.createTextMessage("Message " + ": " + i);
messageProducer.send(message);
}
} catch (Exception ex) {
ex.printStackTrace();
}
一個JMS接收者也是類似的流程,每次都要撰寫重複的流程有些麻煩,您可以利用Spring所提供的JmsTemplate來簡化程式的撰寫。
以下範例假設您在Glassfish上建立了ConnectionFactory,JNDI名稱為"jms/HelloQueueFactory",以及一個Queue,JNDI名稱為"jms/HelloQueue"。
ConnectionFactory與Queue的建立,都可以交由Spring容器,之後您可以建立JmsTemplate,並將Spring容器中的 ConnectionFactory、Queue注入JmsTemplate的實例中,例如您可以這麼撰寫beans-config.xml:
- beans-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="jmsFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jms/HelloQueueFactory" />
</bean>
<bean id="myQueue"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jms/HelloQueue" />
</bean>
<bean id="jmst" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="jmsFactory"/>
</property>
<property name="defaultDestination">
<ref bean="myQueue"/>
</property>
</bean>
</beans>
若要傳送訊息,則從容器中取得JmsTemplate的實例,並呼叫對應方法傳送即可,例如:
- MessageProvider.java
package lab7.ex3;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
public class MessageProvider {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext(
"lab7/ex3/beans-config.xml");
JmsTemplate jmst = (JmsTemplate) context.getBean("jmst");
jmst.convertAndSend("Hello World!");
}
}
JmsTemplate會自動為您建立Connection、Session、Message並進行傳送,而訊息的處理者可以如下撰寫:
- MessageConsumer.java
package lab7.ex3;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
public class MessageConsumer {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext(
"lab7/ex3/beans-config.xml");
JmsTemplate jmst = (JmsTemplate) context.getBean("jmst");
System.out.println(jmst.receiveAndConvert());
}
}
訊息傳送者傳送一個"Hello World!",所以您會在訊息接收之後,於主控台下看到顯示"Hello World!"。