spring-RMI及底层实现原理

Java远程方法调用,即Java RMI(Java Remote Method Invocation),是java里一种实现远程过程调用的应用程序编程接口。java RMI极大地依赖于接口。在需要创建一个远程对象时,程序员通过传递一个接口来隐藏底层的实现细节。客户端得到的远程对象句柄正好与本地的桩代码连接,由后者负责透过网络通信。这样一来,程序员只需关心如何通过自己的接口句柄发送消息。
在spring中,同样提供了对RMI的支持,使得在spring下的RMI开发变得更方便。

/**
 * 服务接口
 */
public interface HelloRMIService {
    int getAdd(int a,int b);
}
/**
 * 服务端接口实现
 */
@Component
public class HelloRMIServiceImpl implements HelloRMIService {
    @Override
    public int getAdd(int a, int b) {
        return a+b;
    }
}
@Configuration
public class RmiConfig {

    /**
     * 服务端发布注册
     */
    @Bean
    public RmiServiceExporter rmiServiceExporter(HelloRMIServiceImpl helloRMIService){
        RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
        rmiServiceExporter.setService(helloRMIService);
        rmiServiceExporter.setServiceName("helloRMI");
        rmiServiceExporter.setRegistryPort(9999);
        rmiServiceExporter.setServiceInterface(HelloRMIService.class);
        return rmiServiceExporter;
    }

    /**
     * 往spring环境注册一个客户端调用服务接口的实例
     * 正常情况下,可以定义在远程客户端环境
     */
    @Bean(name = {"myClient"})
    public RmiProxyFactoryBean proxyFactoryBean(){
        RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
        rmiProxyFactoryBean.setServiceUrl("rmi://127.0.0.1:9999/helloRMI");
        rmiProxyFactoryBean.setServiceInterface(HelloRMIService.class);
        return rmiProxyFactoryBean;
    }
}
@RestController
public class RmiController {

    @Autowired
    ApplicationContext applicationContext;

    @GetMapping("/getAdd")
    public int getAdd(){
        HelloRMIService myClient = applicationContext.getBean("myClient", HelloRMIService.class);
        return myClient.getAdd(1,2);
    }

}

以上过程,客户端通过RMI进行了远程连接,连接到了服务端,使用服务端提供方法返回结果。接下来我们一起深入分析spring中对RMI功能的实现原理。

服务端实现:

我们知道RmiServiceExporter类是发布RMI的关键类。
spring-RMI及底层实现原理_第1张图片
spring-RMI及底层实现原理_第2张图片
spring-RMI及底层实现原理_第3张图片
spring-RMI及底层实现原理_第4张图片
服务端RMI服务激活调用:

由于之前bean初始化的时候做了服务名称绑定this.registry.bind(this.serviceName,this.exportedObject),其中exportedObject其实是被RMIInvocationWrapper进行封装过的,也就是说当其它服务器调用serviceName的RMI服务时,java会为我们封装其内部操作,而直接会将代码转向RMIInvocationWrapper的invoke方法中,进而在调用其增强RemoteInvocationTraceInterceptor的invoke方法
spring-RMI及底层实现原理_第5张图片
在这里插入图片描述
spring-RMI及底层实现原理_第6张图片
spring-RMI及底层实现原理_第7张图片
客户端实现:
由上面配置可以看出,客户端的关键类是RmiProxyFactoryBean
spring-RMI及底层实现原理_第8张图片
可见,RmiProxyFactoryBean实现了几个关键接口,FactoryBean、InitializingBean以及Advice增强器
spring-RMI及底层实现原理_第9张图片
spring-RMI及底层实现原理_第10张图片
spring-RMI及底层实现原理_第11张图片
可以猜测客户端的实现应该都是在prepare()方法中
spring-RMI及底层实现原理_第12张图片
spring-RMI及底层实现原理_第13张图片
客户端调用:

spring-RMI及底层实现原理_第14张图片
spring-RMI及底层实现原理_第15张图片
spring-RMI及底层实现原理_第16张图片

还记得上面说过一句话,当其它服务器调用serviceName的RMI服务时,java会为我们封装其内部操作,而直接会将代码转向RMIInvocationWrapper的invoke方法中
spring-RMI及底层实现原理_第17张图片

你可能感兴趣的:(spring,spring)