服务接口:
package com.zzj.jndi.service;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface JndiService extends Remote {
public int getNext() throws RemoteException;
}
服务实现类:package com.zzj.jndi.service.impl;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import com.zzj.jndi.service.JndiService;
/**
* Unicast:单播(点到点)
* @author lenovo
*
*/
public class JndiServiceImpl extends UnicastRemoteObject implements JndiService {
private static final long serialVersionUID = 1L;
private int next;
public JndiServiceImpl() throws RemoteException {
super();
}
/**
* 非线程安全的
*/
public int getNext() throws RemoteException {
return ++next;
}
}
发布服务:
package com.zzj.jndi.provider;
import java.rmi.registry.LocateRegistry;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import com.zzj.jndi.service.JndiService;
import com.zzj.jndi.service.impl.JndiServiceImpl;
public class RmiServiceProvider {
final static String CONTEXT_FACTORY = "com.sun.jndi.rmi.registry.RegistryContextFactory";
final static String PROVIDER_URL = "rmi://localhost:8080";
public static void main(String[] args) throws Exception {
//注册RMI服务器端口
LocateRegistry.createRegistry(8080);
Hashtable<String, Object> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
Context ctx = new InitialContext(env);
JndiService jndiService = new JndiServiceImpl();
ctx.bind("jndiService", jndiService);
System.out.println("Jndi服务已绑定...");
}
}
服务提供者启动之后,会开启端口监听来自客户端的请求。
客户端:
package com.zzj.jndi.client;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import com.zzj.jndi.service.JndiService;
public class RmiJndiClient {
final static String CONTEXT_FACTORY = "com.sun.jndi.rmi.registry.RegistryContextFactory";
final static String PROVIDER_URL = "rmi://localhost:8080";
public static void main(String[] args) throws Exception {
Hashtable<String, Object> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
Context ctx = new InitialContext(env);
JndiService jndiService = (JndiService) ctx.lookup("jndiService");
for (int i = 0; i < 5; i++) {
System.out.println(jndiService.getNext());
}
System.out.println("-------------------");
JndiService jndiService2 = (JndiService) ctx.lookup("jndiService");
for (int i = 0; i < 5; i++) {
System.out.println(jndiService2.getNext());
}
}
}
客户端运行结果:1
2
3
4
5
-------------------
6
7
8
9
10
再次运行客户端:11
12
13
14
15
-------------------
16
17
18
19
20
由运行结果可知:RMI绑定的对象是单例的,如果在绑定的对象中有成员变量,则会有线程安全的问题。