RPC:
所谓RPC,其实就是将以前由我们自己在本地声明方法,并调用,变成方法声明在其他服务器中,远程调用方法的执行,方法的执行发生在远程的服务器中。其中,调用远程方法的称为服务消费者,提供远程方法执行的叫做服务器的提供者。
RMI方式:
- 实现了服务消费发起请求到服务器提供者,服务提供者调用起方法完成功能处理
- 后将处理结果响应给服务器消费者。
- 遵循的协议:RMI协议
- 特点:RMI方式是Java自带的方式。
- 使用:参照源码
- 总结:
- RMI实现RPC是基于动态代理方式实现的。(JDK动态代理)
- 真实对象在服务提供者
- 代理对象在服务消费者中。
- 而代理对象中的代理方法实现了远程调用真实方法。
- 注意:
- 在使用RMI时,基于远程访问的接口,必须在服务消费者服务提供者中都要声明。
- 我们需要使用Maven工具将不同项目都要使用的类资源单独打包存放。
代码
1.服务接口 单独作为一个maven项目
package com.bjsxt.service;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 需要被远程调用的方法所在的接口必须继承Remote接口。
*
* @author Administrator
*
*/
public interface UserService extends Remote{
/**
* 因为该方法是可能被远程调用,需要抛出远程调用的异常
* @param name
* @return
* @throws RemoteException
*/
public String sayHello(String name) throws RemoteException;
}
2.服务提供方
service实现类
package com.bjsxt.service.impl;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import com.bjsxt.service.UserService;
public class UserServiceImpl extends UnicastRemoteObject implements UserService{
public UserServiceImpl() throws RemoteException {
super();
}
@Override
public String sayHello(String name) throws RemoteException {
return "Hello"+name;
}
}
启动服务
package com.bjsxt.main;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import com.bjsxt.service.UserService;
import com.bjsxt.service.impl.UserServiceImpl;
public class RmiProviderApp {
public static void main(String[] args) {
/****
* 启动jvm,发布远程服务
*/
try {
//注册发布的远程服务的访问端口
LocateRegistry.createRegistry(8888);
//定义访问远程服务的URL
String name="rmi://localhost:8888/rmi";
//创建UserServiceImpl实现类对象,提供远程服务的对象
UserService userService = new UserServiceImpl();
//该提供远程服务的对象,绑定一个URL
Naming.bind(name, userService);
System.out.println("===========发布rmi远程服务============");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.服务消费方
package com.bjsxt.main;
import java.rmi.Naming;
import com.bjsxt.service.UserService;
public class RmiConsumerApp {
public static void main(String[] args) {
/***
* 启动jvm,完成服务的消费
*/
try {
//定义访问远程服务的URL
String name="rmi://localhost:8888/rmi";
//通过url获得服务的远程代理对象
UserService userService=(UserService) Naming.lookup(name);
System.out.println("---"+userService.getClass());
//调用远程方法
String result = userService.sayHello("小强");
System.out.println("result="+result);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}