通过JMS初步理解JNDI

JNDI服务模型
jndi-model

1、服务端

package com.neohope.jndi.test;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.Hashtable;

/**
 * Created by Hansen on 2016/5/4.
 */
public class Server {
    private static InitialContext ctx;

    public static void initJNDI() {
        try {
            LocateRegistry.createRegistry(1234);
            final Hashtable jndiProperties = new Hashtable();
            jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
            jndiProperties.put(Context.PROVIDER_URL, "rmi://localhost:1234");
            ctx = new InitialContext(jndiProperties);
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public static void bindJNDI(String name, Object obj) throws NamingException {
        ctx.bind(name, obj);
    }

    public static void unInitJNDI() throws NamingException {
        ctx.close();
    }

    public static void main(String[] args) throws NamingException, IOException {
        initJNDI();
        NeoMessage msg = new NeoMessage("Just A Message");
        bindJNDI("java:com/neohope/jndi/test01", msg);
        System.in.read();
        unInitJNDI();
    }
}

2、客户端

package com.neohope.jndi.test;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;

/**
 * Created by Hansen
 */
public class Client {
    public static void main(String[] args) throws NamingException {
        final Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
        jndiProperties.put(Context.PROVIDER_URL, "rmi://localhost:1234");

        InitialContext ctx = new InitialContext(jndiProperties);
        NeoMessage msg = (NeoMessage) ctx.lookup("java:com/neohope/jndi/test01");
        System.out.println(msg.message);
        ctx.close();
    }
}

3、NeoMessage

package com.neohope.jndi.test;

import java.io.Serializable;
import java.rmi.Remote;

/**
 * Created by Hansen
 */
public class NeoMessage implements Remote, Serializable {
    public String message = "";

    public NeoMessage(String message)
    {
        this.message = message;
    }
}

大家可以看出,在这个简单的例子中:
1、服务端仅仅是把数据生成好,放到了LocateRegistry中。
2、而客户端,通过JNDI查到消息,获取到了对应的数据。
3、LocateRegistry完成了跨JVM/主机通讯的任务

反过来思考一下,对于JNDIL是不是更清楚一些了呢?
那再思考一下,那J2EE容器中的数据源是如何统一管理的呢?

JBoss EAP JMS的调用(Queue)

通讯流程图
jms-point-to-point-model.png

首先是Server端的开发及设置:
1、增加一个用户:

bin\add-user.bat

用户名密码随便,但要属于guest组

2、启动Server

standalone.bat -server-config=standalone-full.xml 

3、新建Queue

jboss-cli.bat --connect
jms-queue add --queue-address=jmsQueue --entries=queue/jmsQueue,java:jboss/exported/jms/queue/jmsQueue

到这里服务端已经完成了。

然后是客户端的设置:
1、Sender

package com.neohope.jms.test;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;

/**
 * Created by Hansen
 */
public class TestQueueSender {
    public static void main(String[] args) throws NamingException, JMSException {

        final Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
        final InitialContext ctx = new InitialContext(jndiProperties);

        QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
        QueueConnection connection = factory.createQueueConnection("user001", "user001#");
        QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);

        Queue queue = (Queue) ctx.lookup("jms/queue/jmsQueue");
        TextMessage msg = session.createTextMessage("Queue Test Messagee");
        QueueSender sender = session.createSender(queue);
        sender.send(msg);


        session.close();
        connection.close();
    }
}

2、Receiver

package com.neohope.jms.test;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.IOException;
import java.util.Hashtable;

/**
 * Created by Hansen
 */
public class TestQueueReceiver {
    public static void main(String[] args) throws NamingException, JMSException, IOException {

        final Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
        final InitialContext ctx = new InitialContext(jndiProperties);

        QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
        QueueConnection connection = factory.createQueueConnection("user001", "user001#");
        QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);

        Queue queue = (Queue) ctx.lookup("jms/queue/jmsQueue");
        QueueReceiver receiver = session.createReceiver(queue);
        receiver.setMessageListener(new MessageListener() {
            public void onMessage(Message message) {
                try{
                    TextMessage msg=(TextMessage)message;
                    System.out.println("Queue message received:"+msg.getText());
                }
                catch(JMSException e)
                {
                    System.out.println(e);
                }
            }});

        connection.start();
        System.in.read();

        session.close();
        connection.close();
    }
}

JBoss EAP JMS的调用(Topic)

通讯流程图
jms-publisher-subscriber-model.png

首先是Server端的开发及设置:
1、增加一个用户:

bin\add-user.bat

用户名密码随便,但要属于guest组

2、启动Server

standalone.bat -server-config=standalone-full.xml 

3、新建Topic

jboss-cli.bat --connect
jms-topic add --topic-address=jmsTopic --entries=topic/jmsTopic,java:jboss/exported/jms/topic/jmsTopic

到这里服务端已经完成了。

然后是客户端的设置:
1、Publisher

package com.neohope.jms.test;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;

/**
 * Created by Hansen
 */
public class TestTopicPublisher {
    public static void main(String[] args) throws NamingException, JMSException {
        final Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
        final InitialContext ctx = new InitialContext(jndiProperties);


        TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
        TopicConnection connection = factory.createTopicConnection("user001", "user001#");
        TopicSession session = connection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);

        Topic topic = (Topic) ctx.lookup("jms/topic/jmsTopic");
        TextMessage msg = session.createTextMessage("Topic Test Message");
        TopicPublisher publisher = session.createPublisher(topic);
        publisher.publish(msg);

        session.close();
        connection.close();
    }
}

2、Subscriber

package com.neohope.jms.test;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.IOException;
import java.util.Hashtable;

/**
 * Created by Hansen
 */
public class TestTopicSubscriber {
    public static void main(String[] args) throws NamingException, JMSException, IOException {
        final Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
        final InitialContext ctx = new InitialContext(jndiProperties);


        TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
        TopicConnection connection = factory.createTopicConnection("user001", "user001#");
        TopicSession session = connection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);

        Topic topic = (Topic) ctx.lookup("jms/topic/jmsTopic");
        TopicSubscriber subscriber = session.createSubscriber(topic);
        subscriber.setMessageListener(new MessageListener() {
            public void onMessage(Message message) {
                try {
                    TextMessage msg = (TextMessage) message;
                    System.out.println("Topic message received:" + msg.getText());
                } catch (JMSException e) {
                    System.out.println(e);
                }
            }
        });

        connection.start();
        System.in.read();

        session.close();
        connection.close();
    }
}