使用 RMI 实现方法的远程调用
RMI介绍
RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。
rmi公共资源(不管是提供者还是消费者都需要)
package com.zxw.service;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* Remote:标识其方法可以从非本地虚拟机上调用
* (个人理解:别的客户机通过UserService接口调用其实现类UserServiceImpl的方法)
*
* 创建 需要发布的服务 对应的业务接口
*/
public interface UserService extends Remote {
public String helloRmi(String name) throws RemoteException;
}
服务提供者
添加公共资源的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>RmiDemo</artifactId>
<groupId>com.zxw</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>RmiProvider</artifactId>
<dependencies>
<dependency>
<groupId>com.zxw</groupId>
<artifactId>RmiResources</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
接口实现类
package com.zxw.service.impl;
import com.zxw.service.UserService;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* UnicastRemoteObject:实现 Remote 远程对象的导出
* (调用其无参构造,其无参构造再调用其父类的无参构造,
* protected UnicastRemoteObject() throws RemoteException
* {
* this(0);
* }
* 父类无参构造调用一个参数的方法
* 该一个参数的方法是导出远程对象
* protected UnicastRemoteObject(int port) throws RemoteException
* {
* this.port = port;
* exportObject((Remote) this, port);
* }
* )
*/
public class UserServiceImpl extends UnicastRemoteObject implements UserService {
public UserServiceImpl() throws RemoteException {
super();//调用父类无参构造
}
public String helloRmi(String name) throws RemoteException {
return "hello"+name;
}
}
发布远程服务
package com.zxw.app;
import com.zxw.service.UserService;
import com.zxw.service.impl.UserServiceImpl;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
/**
* 发布远程服务
*/
public class ProviderApp {
/**
* Naming:给提供远程服务的对象的绑定 url(生产者)
* 通过远程的url,获得提供远程服务的代理对象(消费者)
* LocateRegistry:指定发布的远程服务的方法接口
* @param args
*/
public static void main(String[] args) {
try {
//将远程服务发布到本地的8888端口
LocateRegistry.createRegistry(8888);
//发布远程服务的访问url(消费者通过该rul访问生产者发布的远程服务,远程服务的具体实现有UserServiceImpl实现)
String name="rmi://localhost:8888/rmi";
//创建一个提供具体服务的对象
UserService us = new UserServiceImpl();
//给提供远程服务的对象绑定一个url
Naming.bind(name,us);
System.out.println("====rmi远程发布====");
}catch (Exception e){
e.printStackTrace();
}
}
}
结果:
服务消费者
添加公共资源依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>RmiDemo</artifactId>
<groupId>com.zxw</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>RmiConsumer</artifactId>
<dependencies>
<dependency>
<groupId>com.zxw</groupId>
<artifactId>RmiResources</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
接口实现类
package com.zxw.service.impl;
import com.zxw.service.UserService;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class UserServiceImpl extends UnicastRemoteObject implements UserService {
public UserServiceImpl() throws RemoteException {
super();//调用父类无参构造
}
public String helloRmi(String name) throws RemoteException {
return "hello"+name;
}
}
消费远程服务
package com.zxw.app;
import com.zxw.service.UserService;
import java.rmi.Naming;
public class ConsumerApp {
/**
* Naming:给提供远程服务的对象的绑定 url(生产者)
* 通过远程的url,获得提供远程服务的代理对象(消费者)
* @param args
*/
public static void main(String[] args) {
try {
//url
String name="rmi://localhost:8888/rmi";
//通过生产者发布的url获得提供远程服务的代理对象
UserService userService =(UserService)Naming.lookup(name);
System.out.println("获取的远程服务的代理对象:"+userService);
//通过远程服务的代理对象调用远程服务的具体方法
String helloRmi = userService.helloRmi("zxw");
System.out.println(helloRmi);
}catch (Exception e){
e.printStackTrace();
}
}
}
结果: