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的关键类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
服务端RMI服务激活调用:

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

还记得上面说过一句话,当其它服务器调用serviceName的RMI服务时,java会为我们封装其内部操作,而直接会将代码转向RMIInvocationWrapper的invoke方法中
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring为各种远程访问技术提供集成工具类。Spring远程访问通过使用普通POJOs,能更容易的开发远程访问服务。目前,Spring远程访问的主要技术如下: 1. 远程调用RMI(Remote Method Invocation): 通过使用 RmiProxyFactoryBean 和 RmiServiceExporter,并且,Spring支持两个传统的RMI(使用 java.rmi.Remote接口和java.rmi.RemoteException)和通过RMI调用器实现的暴露远程调用(支持任何Java接口)。 2. Spring的HTTP调用器(Spring’s Http Invoker): Spring提供了一种特殊的允许通过HTTP进行Java串行化的远程调用策略,支持任意Java接口(就像RMI调用器)。相对应的支持类是 HttpInvokerProxyFactoryBean和 HttpInvokerServiceExporter。 3. Hessian: 通过 HessianProxyFactoryBean 和 HessianServiceExporter,可以使用Caucho提供的基于HTTP的轻量级二进制协议来透明地暴露服务。 4. Burlap: Burlap是Caucho的另外一个子项目,可以作为Hessian基于XML的替代方案。Spring提供了诸如 BurlapProxyFactoryBean 和 BurlapServiceExporter 的支持类。 5. JAX RPC: Spring通过JAX-RPC为远程Web服务提供支持(J2EE 1.4's web service API)。 6. JAX-WS:Spring通过JAX-WS为远程Web服务提供支持(the successor of JAX-RPC, as introduced in Java EE 5 and Java 6)。 7. JMS:远程访问通过类JmsInvokerServiceExporter和JmsInvokerProxyFactoryBean使用JMS的底层协议实现。 二. 远程访问------RMI 1. RMI远程访问基本流程 1). 服务端定义远程访问接口; 2). 服务端通过RmiServiceExporter暴露服务接口 3). 客户端定义与服务端已暴露的相同接口 4). 客户端通过RmiProxyFactoryBean调用服务接口
### 回答1: Java RMI(远程方法调用)是一种用于在分布式系统中进行远程通信的Java API。虽然它提供了方便的远程方法调用功能,但也存在一些安全漏洞。 其中一个漏洞是未经授权的远程方法调用(Unauthorized Remote Method Invocation)。在Java RMI中,远程对象可以通过URL公开,并接受来自任何Java虚拟机的调用。如果没有正确的安全措施,攻击者可以利用这个漏洞,通过发送恶意请求来执行未经授权的远程方法调用。这可能导致敏感数据泄露、服务拒绝、远程代码执行等安全风险。 另一个漏洞是远程代码执行(Remote Code Execution)。由于Java RMI允许将类作为参数传递给远程方法调用,攻击者可以通过构建恶意类来在远程系统中执行任意代码。这可能会导致远程系统被完全控制,从而对系统进行非法操作、运行恶意软件等。 为了防止这些漏洞,应采取以下安全措施: 1.授权策略:通过使用Java RMI的安全管理器,对远程调用进行授权验证。只允许受信任的主机或用户执行远程方法调用。 2.数据验证:在接受远程方法调用之前,对传入的数据进行验证和过滤,以防止恶意输入。 3.安全传输层:使用安全通信协议(如SSL/TLS)对Java RMI进行加密,以保护数据在网络传输过程中的安全性。 4.类过滤:限制远程对象所需的类只能从特定的类路径加载,以防止远程代码执行。 总之,Java RMI漏洞存在一定的风险,但通过使用适当的安全措施可以有效地减少这些风险。 ### 回答2: Java RMI (Remote Method Invocation)是Java中用于远程调用方法的技术,它允许在不同主机上的Java虚拟机之间进行通信和交互。然而,Java RMI中存在一些漏洞,可能导致安全问题。下面是一些常见的Java RMI漏洞: 1. 未授权访问:在没有适当访问控制的情况下,攻击者可能能够直接访问Java RMI服务,获取敏感信息或执行恶意操作。 2. 服务猝死:如果不正确地实现了Java RMI服务,攻击者可能通过发送恶意请求来导致服务崩溃或拒绝服务,导致系统不可用。 3. 反序列化漏洞:由于Java RMI使用Java序列化来传输对象,因此未进行适当的反序列化验证可能导致反序列化漏洞,攻击者可以利用此漏洞在目标系统上执行任意代码。 4. 中间人攻击:由于Java RMI缺乏加密机制,攻击者可能能够拦截和篡改Java RMI通信,以获取敏感信息或篡改数据。 为了解决这些漏洞,可以采取以下措施: 1. 实施访问控制:确保只有经过授权的用户能够访问Java RMI服务,并且只有必要的方法和数据暴露给客户端。 2. 安全配置:在构建Java RMI服务时,应遵循安全最佳实践,确保已正确配置安全管理器和策略文件,以限制服务的操作和访问范围。 3. 验证和过滤输入:在处理Java RMI请求时,始终进行输入验证和过滤,以防止恶意输入和攻击。 4. 反序列化信任:避免直接反序列化不受信任的数据,可以使用白名单或其他验证机制来限制反序列化操作。 5. 加密通信:考虑使用安全的通信协议(如SSL/TLS)来保护Java RMI通信的机密性和完整性,以防止中间人攻击。 总之,了解Java RMI漏洞并采取适当的防护措施是确保Java RMI应用程序安全的重要步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值