首页 > 编程语言 > 详细

Java基础 - RMI概述

时间:2019-07-15 18:06:38      阅读:68      评论:0      收藏:0      [点我收藏+]

RMI简介

Java RMI,即远程方法调用(Remote Method Invocation),一种用于实现远程过程调用RPC(Remote procedure call)的Java API,能直接传输序列化后的Java对象和分布式垃圾收集。它的实现依赖于Java虚拟机(JVM),因此它仅支持从一个JVM到另一个JVM的调用。

技术分享图片

RMI的实现

(1) 直接使用Registry实现RMI

服务端:

public class RegistryService {
    public static void main(String[] args) {
        try {
            //本地主机上的远程对象注册表Registry的实例,默认端口1099
            Registry registry = LocateRegistry.createRegistry(1099);
            //创建一个远程对象
            TestRegistryFacade test = new TestRegistryFacadeImpl();
            //把远程对象注册到RMI注册服务器上,并命名为TestRegistryFacade
            registry.rebind("TestRegistryFacade", test);
            System.out.println("======= 启动RMI服务成功! =======");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

接口:

public interface TestRegistryFacade extends Remote {
    String helloWorld(String name) throws RemoteException;
}

接口实现:

public class TestRegistryFacadeImpl extends UnicastRemoteObject implements TestRegistryFacade {

    public TestRegistryFacadeImpl() throws RemoteException {
        super();
    }

    @Override
    public String helloWorld(String name) {
        return "[Registry] 你好! " + name;
    }
}

客户端:

public class RegistryClient {
    public static void main(String[] args) {
        try {
            Registry registry = LocateRegistry.getRegistry(1099);
            TestRegistryFacade hello = (TestRegistryFacade) registry.lookup("TestRegistryFacade");
            String response = hello.helloWorld("Helios");
            System.out.println("=======> " + response + " <=======");
        } catch (NotBoundException | RemoteException e) {
            e.printStackTrace();
        }
    }
}

注:

Registry(注册表)是放置所有服务器对象的命名空间。
每次服务端创建一个对象时,它都会使用bind()或rebind()方法注册该对象。
这些是使用称为绑定名称的唯一名称注册的。

要调用远程对象,客户端需要该对象的引用,如(TestRegistryFacade)。
即通过服务端绑定的名称(TestRegistry)从注册表中获取对象(lookup()方法)。

(2) 使用Naming方法实现RMI

服务端:

public class NamingService {
    public static void main(String[] args) {
        try {
            //本地主机上的远程对象注册表Registry的实例
            LocateRegistry.createRegistry(1100);
            //创建一个远程对象
            TestNamingFacade test = new TestNamingFacadeImpl();
            //把远程对象注册到RMI注册服务器上,并命名为test
            //绑定的URL标准格式为:rmi://host:port/name
            Naming.bind("rmi://localhost:1100/TestNamingFacade", test);
            System.out.println("======= 启动RMI服务成功! =======");
        } catch (RemoteException | MalformedURLException | AlreadyBoundException e) {
            e.printStackTrace();
        }
    }
}

接口:

public interface TestNamingFacade extends Remote {
    String helloWorld(String name) throws RemoteException;
}

接口实现:

public class TestNamingFacadeImpl extends UnicastRemoteObject implements TestNamingFacade {

    public TestNamingFacadeImpl() throws RemoteException {
        super();
    }

    @Override
    public String helloWorld(String name) {
        return "[Registry] 你好! " + name;
    }
}

客户端:

public class NamingClient {
    public static void main(String[] args) {
        try {
            String remoteAddr = "rmi://localhost:1100/TestNamingFacade";
            TestNamingFacade hello = (TestNamingFacade) Naming.lookup(remoteAddr);
            String response = hello.helloWorld("Helios");
            System.out.println("=======> " + response + " <=======");
        } catch (NotBoundException | RemoteException | MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

Naming其实是对Registry的一个封装。

(3) SpringBoot实现RMI

服务端:

@Configuration
public class RmiServiceConfig {
    @Bean
    public RmiServiceExporter registerService(UserFacade userFacade) {
        RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
        rmiServiceExporter.setServiceName("UserInfo");
        rmiServiceExporter.setService(userFacade);
        rmiServiceExporter.setServiceInterface(UserFacade.class);
        rmiServiceExporter.setRegistryPort(1101);
        return rmiServiceExporter;
    }
}

客户端:

@Configuration
public class RmiClientConfig {
    @Bean
    public UserFacade userInfo() {
        RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
        rmiProxyFactoryBean.setServiceUrl("rmi://localhost:1101/UserInfo");
        rmiProxyFactoryBean.setServiceInterface(UserFacade.class);
        rmiProxyFactoryBean.afterPropertiesSet();
        return (UserFacade) rmiProxyFactoryBean.getObject();
    }
}

客户端测试:

@Autowired
private UserFacade userFacade;
    
@Test
public void userBySexTest() {
    try {
        List<User> userList = userFacade.getBySex("男");
        userList.forEach(System.out::println);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

 

 

转自:https://www.jianshu.com/p/de85fad05dcb

Java基础 - RMI概述

原文:https://www.cnblogs.com/helios-fz/p/11190247.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!