• Java基础


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

    RMI概述

    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();
        }
    }
  • 相关阅读:
    中值滤波与图像锐化
    空间域图像增强
    图像的几何变换
    Fourier分析应用
    Gale-Shapley算法
    有理数与无限循环小数
    线性可分支持向量机
    拉格朗日乘子法+KKT条件
    点到平面的距离
    BP神经网络
  • 原文地址:https://www.cnblogs.com/helios-fz/p/11190247.html
Copyright © 2020-2023  润新知