1.发布/订阅模型在发布/订阅模型(Pub-Sub)中,每个消息被发送到一个消息主题,该主题可以拥有多个订阅者。JMS系统负责将消息的副本传给该主题的每个订阅者。Pub-Sub消息模型与PTP消息模型的不同点:对于Pub-Sub消息模型而言,当多个消息消费者同时订阅某个主题时,只要有一个消息生产者向该主题发布一条消息,每个消费者都可以收到一个消息的副本。而对于PTP消息模型来说,当消息生产者向消息队列发送一条消息之后,只有一个消息消费者可以接收到该消息。对于Pub-Sub消息模型,当消息生产者将某个消息发布到指定主题时,即使某个消息消费者订阅了该主题,但如果该消息抵达消息主题时该消息消费者处于离线状态,它将无法收到该消息。而对于PTP消息模型来说,当消息生产者向消息队列发送一条消息时,即使消息消费者处于离线状态,只要该消息还处于有效期之内,该消息消费者总可以从消息队列中提取到该消息。2.编程实例我们在WebLogic服务器中配置了一个JNDI名为“topic”的主题,它可以作为Pub-Sub消息模型的消息目的地来使用。WebLogic服务器中提供了默认的连接工厂,其JNDI名为“weblogic.jms.ConnectionFactory”。发送消息到主题的代码如下:public class TopicMessageSender{
public void sendMessage() throws Exception{
final String CONNECTION_FACTORY_JNDI = "weblogic.jms.ConnectionFactory";
Context ctx = getInitialContext();
ConnectionFactory connFactory = (ConnectionFactory)ctx.lookup(CONNECTION_FACTORY_JNDI);
Destination dest = (Destination)ctx.lookup("topic");
Connection conn = connFactory.createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer sender = session.createProducer(dest);
sender.setDeliveryMode(DeliveryMode.PERSISTENT);
sender.setTimeToLive(20000);
TextMessage msg = session.createTextMessage();
msg.setText("Hello JMS");
sender.send(msg);
msg.setText("The time is "+new Date().toString());
sender.send(msg);
session.close();
conn.close();
}
private Context getInitialContext(){
final String INIT_FACTORY = "weblogic.jndi.WLInitialContextFactory";
final String SERVER_URL = "t3://localhost:7001";
Context ctx = null;
try{
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, INIT_FACTORY);
props.put(Context.PROVIDER_URL, SERVER_URL);
ctx = new InitialContext(props);
}catch(NamingException ne){
System.out.println("can't connect the WebLogic " + SERVER_URL);
ne.printStackTrace();
}
return ctx;
}
public static void main(String[] args) throws Exception{
TopicMessageSender mp = new TopicMessageSender();
mp.sendMessage();
}
}
从消息主题中读取消息的代码如下:
public class Consumer {
public void receiveMessage() throws Exception {
final String CONNECTION_FACTORY_JNDI = "weblogic.jms.ConnectionFactory";
Context ctx = getInitialContext();
ConnectionFactory connFactory = (ConnectionFactory) ctx
.lookup(CONNECTION_FACTORY_JNDI);
Topic dest = (Topic) ctx.lookup("topic");
Connection conn = connFactory.createConnection();
conn.setClientID("landingbj");
conn.start();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer receiver = session.createDurableSubscriber(dest,
"landingbj");
TextMessage msg = (TextMessage) receiver.receive();
if (msg != null) {
System.out.println(msg);
System.out.println("The message: " + msg.getText());
}else{
System.out.println("No message can be shown!");
}
session.close();
conn.close();
}
private Context getInitialContext() {
final String INIT_FACTORY = "weblogic.jndi.WLInitialContextFactory";
final String SERVER_URL = "t3://localhost:7001";
Context ctx = null;
try {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, INIT_FACTORY);
props.put(Context.PROVIDER_URL, SERVER_URL);
ctx = new InitialContext(props);
} catch (NamingException ne) {
System.out.println("can't connect the WebLogic " + SERVER_URL);
ne.printStackTrace();
}
return ctx;
}
public static void main(String[] args) throws Exception {
Consumer c = new Consumer();
c.receiveMessage();
}
}