支持和实现,象IBM的MQSeries,SonicMQ,Weblogic..
jms提供了二个基本模型,pub/sub( publish/subscribe ) 和 P2P ( point to point ). pub/sub model,简单来
说就是发布订阅模型,在网络中的任一一台机器都可以作为jms的信息发布者(sender)或订阅者(receiver),sender将
组织完的message放到topics里,receivers从topics里取得message信息,这是一个典型的pull-base model. P2P model
,点对点模式,信息发布者将信息放送到queues,client端可以从queues里取得信息,与pub/sub模式不同的是,queues里的
每一个message只能由一个jms client接受.
所有的这些机制,均有MOM(Message-oriented Middleware)提供,而对于信息的发布者和接收者来说,他们彼此之间是
松偶合的,并没有直接的消息通讯,而是通过中间件。这种loosely couple特性,使得jms十分适合在企业信息整合
(EAI Enterprise Application Integration)中使用.当然,对于企业遗留系统来说,相互之间的信息交换的技术还有很多,
RPC,XML-RPC,SOAP 都是比较好的技术.jms相比较这些技术,最明显的优势是jms使的信息的发布者和接收者之间是松偶合的,
并且是异步的。这也提供了良好的扩展性和性能上的优势。
JMS提供了多种类型的消息.
1.TextMessage 包含了Java.lang.String为信息的内容,当然也可以存放xml的String类型,灵活性还是比较大的。
2.ObjectMessage 包含串行化的java对象。
3.BytesMessage 包含简单的字节数组。
4.StreamMessage 包含java原始类型的流对象。
5.MapMessage 包含名称-值对内容,这里的值只能是原始类型或他们的外附对象。
一个实际的例子,首先我们在webogic8.1里建立2个JMS连接工厂,一个给TopicSender使用,另一个则分配给TopicReceiver使用
okay,首先建立TopicSender:
/*
* Created on 2005-5-7
*
*/
package org.jjyao.jms;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import org.apache.log4j.Logger;
/**
* JMS
*
* @author jjyao 2005-5-7
*/
public class TopicSender {
private final static Logger logger = Logger.getLogger(TopicSender.class);
/**
* Defines jndi factory name for weblogic
*/
private final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
/**
* Defines jndi factory name for jms
*/
private final static String JMS_FACTORY = "weblogic.jms.TopicConnectionFactory";
/**
* Defines jndi name for topic
*/
private final static String TOPIC = "weblogic.jms.topic";
/**
* Defines the url
*/
private final static String PROVIDER_URL = "t3://localhost:7001";
private TopicConnectionFactory tconFactory;
private TopicConnection tcon;
private TopicSession tsession;
private TopicPublisher tPublisher;
private Topic topic;
private TextMessage msg;
/**
*
* @param ctx
* @throws ClassCastException
* @throws NamingException
* @throws JMSException
*/
public void init(Context ctx) throws ClassCastException, NamingException, JMSException {
tconFactory = (TopicConnectionFactory) PortableRemoteObject.narrow(ctx.lookup(JMS_FACTORY),
TopicConnectionFactory.class);
tcon = tconFactory.createTopicConnection();
tsession = tcon.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);
topic = (Topic) PortableRemoteObject.narrow(ctx.lookup(TOPIC),Topic.class);
tPublisher = tsession.createPublisher(topic);
msg = tsession.createTextMessage();
if(logger.isInfoEnabled()){
logger.info("tcon : " + tcon);
logger.info("tsession : " + tsession);
logger.info("topic : " + topic);
logger.info("tPublisher : " + tPublisher);
logger.info("msg : " + msg);
}
tcon.start();
}
/**
*
* @throws JMSException
*/
public void close() throws JMSException{
tPublisher.close();
tsession.close();
tcon.close();
}
/**
*
* @param message
* @throws JMSException
*/
public void send(String message) throws JMSException{
this.msg.setText(message);
this.tPublisher.publish(msg);
}
/**
*
* @param sender
* @throws IOException
* @throws JMSException
*/
protected void readAndSend(TopicSender sender) throws IOException, JMSException{
BufferedReader reader = new BufferedReader( new InputStreamReader(System.in));
String line = null;
do{
System.out.println(" Enter message /"quit to quit/" : ");
line = reader.readLine();
if(line != null && !"".equals(line)){
this.send(line);
if(logger.isDebugEnabled()){
logger.debug(" Send jms message : " + line);
}
}
}while( line != null && !"QUIT".equalsIgnoreCase(line));
}
public static void main(String[] args) throws Exception {
Properties env = new Properties();
env.put(Context.SECURITY_PRINCIPAL,"weblogic");
env.put(Context.SECURITY_CREDENTIALS,"weblogic");
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
env.put("weblogic.jndi.createIntermediateContexts", "true");
InitialContext context = new InitialContext(env);
TopicSender topicSender = new TopicSender();
topicSender.init(context);
topicSender.readAndSend(topicSender);
topicSender.close();
}
}
建立TopicReceive:
/*
* Created on 2005-5-8
*
*/
package org.jjyao.jms;
import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import org.apache.log4j.Logger;
/**
* JMS
*
* @author jjyao 2005-5-8
*/
public class TopicReceive implements MessageListener {
private final static Logger logger = Logger.getLogger(TopicReceive.class);
/**
* Defines jndi factory name for weblogic
*/
private final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
/**
* Defines jndi factory name for jms
*/
private final static String JMS_FACTORY = "weblogic.jms.TopicConnectionFactory_2";
/**
* Defines jndi name for topic
*/
private final static String TOPIC = "weblogic.jms.topic";
/**
* Defines the url
*/
private final static String PROVIDER_URL = "t3://localhost:7001";
private boolean quit = false;
private TopicConnectionFactory tconFactory;
private TopicConnection tcon;
private TopicSession tsession;
private TopicSubscriber tSubscriber;
private Topic topic;
/**
*
*/
public void onMessage(Message msg) {
String msgText = null;
try {
if (msg instanceof TextMessage) {
msgText = ((TextMessage) msg).getText();
} else {
msgText = msg.toString();
}
logger.info(" MsgText : " + msgText);
if ("quit".equals(msgText)) {
synchronized (this) {
this.quit = true;
this.notifyAll();
}
}
} catch (JMSException e) {
logger.error(e, e);
}
}
/**
*
* @param ctx
* @throws ClassCastException
* @throws NamingException
* @throws JMSException
*/
private void init(Context ctx) throws ClassCastException, NamingException, JMSException {
tconFactory = (TopicConnectionFactory) PortableRemoteObject.narrow(
ctx.lookup(JMS_FACTORY), TopicConnectionFactory.class);
tcon = tconFactory.createTopicConnection();
tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topic = (Topic) PortableRemoteObject.narrow(ctx.lookup(TOPIC), Topic.class);
tSubscriber = tsession.createSubscriber(topic);
tSubscriber.setMessageListener(this);
if (logger.isDebugEnabled()) {
logger.debug(" tconFactory : " + tconFactory);
logger.debug(" tcon : " + tcon);
logger.debug(" tsession : " + tsession);
logger.debug(" topic : " + topic);
}
tcon.start();
}
/**
*
* @throws JMSException
*/
private void close() throws JMSException {
tSubscriber.close();
tsession.close();
tcon.close();
}
public static void main(String[] args) throws Exception {
Properties env = new Properties();
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "weblogic");
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
env.put("weblogic.jndi.createIntermediateContexts", "true");
InitialContext context = new InitialContext(env);
TopicReceive topicReceive = new TopicReceive();
topicReceive.init(context);
System.out.println("JMS Ready To Receive Messages (To quit, send a /"quit/" message).");
synchronized(topicReceive){
while(!topicReceive.quit){
topicReceive.wait();
}
}
topicReceive.close();
}
}
一个简单的JMS的pub/sub模型就建立好了...