RMI初探



接口


import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IFoo extends Remote {
    String say(String name) throws RemoteException;
}

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IBar extends Remote {
    String buy(String name) throws RemoteException;
}

实现


import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class FooImpl /* extends UnicastRemoteObject */ implements IFoo {

    private int index;

    public FooImpl() throws RemoteException {
        this(0);
    }

    public FooImpl(int port) throws RemoteException {
        // ObjectTable.objTable
        UnicastRemoteObject.exportObject(this, port);
    }

    @Override
    public String say(String name) throws RemoteException {
        String message = "say" + (index++);
        System.out.println(message);
        return name + ": " + message;
    }
}

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class BarImpl implements IBar {

    private int index;

    public BarImpl() throws RemoteException {
        this(0);
    }

    public BarImpl(int port) throws RemoteException {
        // ObjectTable.objTable
        UnicastRemoteObject.exportObject(this, port);
    }

    @Override
    public String buy(String name) throws RemoteException {
        String message = "buy" + (index++);
        System.out.println(message);
        return name + ": " + message;
    }
}

两个对象实例化之后, 观察 ObjectTable 类里的 objTable 和 implTable 属性内容
// sun.rmi.transport.ObjectTable
public final class ObjectTable {
    private static final Map<ObjectEndpoint, Target> objTable = new HashMap();
    private static final Map<WeakRef, Target> implTable = new HashMap();
}

ObjectTable.objTable 属性内容

在这里插入图片描述


ObjectTable.implTable 属性内容

在这里插入图片描述



Server


import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Server {

    public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {

        IBar bar = new BarImpl();
        IFoo foo = new FooImpl();
        //方式一
        Registry registry = LocateRegistry.createRegistry(58082);
        registry.bind("bar", bar);
        //方式二
        Naming.bind("rmi://192.168.31.141:58082/foo", foo);

    }
}

bind 方法会向 RegistryImpl的Hashtable<String, Remote> bindings属性put操作


执行Server的main方法之后, 服务端 registry 对象的属性如下

在这里插入图片描述


ObjectTable.objTable 属性内容里多了一个RegistryImpl_Stub

在这里插入图片描述



服务端会有一个线程(RMI TCP Accept-58082) 监听 58082 端口, 等待客户端的请求

在这里插入图片描述






客户端


import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

    public static void main(String[] args) throws Exception {

        //方式一
        Registry registry = LocateRegistry.getRegistry("192.168.31.141", 58082);
        IFoo foo = (IFoo) registry.lookup("foo");
        System.out.println(foo.say("druid"));

        //方式二
        IBar bar = (IBar) Naming.lookup("rmi://192.168.31.141:58082/bar");
        System.out.println(bar.buy("hikari"));
    }
}


参考文献

1. RMI源码调试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值