Java RMI,即远程方法调用(Remote Method Invocation),一种用于实现远程过程调用RPC(Remote procedure call)的Java API,能直接传输序列化后的Java对象和分布式垃圾收集。它的实现依赖于Java虚拟机(JVM),因此它仅支持从一个JVM到另一个JVM的调用。
服务端:
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()方法)。
服务端:
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的一个封装。
服务端:
@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
原文:https://www.cnblogs.com/helios-fz/p/11190247.html