java - 从服务器在客户端执行的 spring 双向 rmi 回调

标签 java spring proxy callback rmi

在服务器端,我有一个 ListenerManager,它会触发对其 Listener 的回调。使用 Spring RmiServiceExporter

导出管理器

在客户端,我有一个由 RmiProxyFactoryBean 创建的管理器代理,以及一个通过此代理向服务器端的管理器注册的 Listener 实现。

到目前为止一切顺利:ListenerManager 被赋予一个Listener 并调用其回调,但是由于监听器只是客户端对象的反序列化副本,回调在服务器端运行,而不是客户端。

如何让 Spring 在服务器端为客户端监听器生成一个代理,以便服务器调用的回调在客户端远程执行?我当然不需要相反方向的另一对(导出商、代理工厂)?

最佳答案

一个纯RMI解决方案:客户端监听对象需要实现java.rmi.server.UnicastRemoteObject .如果是,它的每个方法都会抛出 RemoteException然后当它通过管理器代理传递到服务器时,一切都自动连接起来,服务器端代理上的方法调用到这个监听器是对真实客户端对象的方法的远程调用。

这样就可以了,但更好的办法是能够包装导出对象而不需要特定的父类(super class)。我们可以使用 CGLIB Enhancer 将监听器“代理”为 UnicastRemoteObject 的子类它还实现了服务接口(interface)。这仍然需要目标对象实现 java.rmi.Remote并声明throws RemoteException .

下一步是一个可以导出任意对象的解决方案以远程调用它们的方法,而不需要它们实现 Remote或声明 throws RemoteException .我们必须将此代理与现有的 Spring 基础设施集成,我们可以通过 RmiBasedExporter 的新实现来做到这一点。以 RmiServiceExporter#prepare() 的非注册表位为模型导出我们代理的 RMI stub 和 RmiClientInterceptor.doInvoke(MethodInvocation, RmiInvocationHandler) 的调用部分.我们需要能够获取服务接口(interface)的导出代理实例。我们可以在 Spring 用于明显“导出”非 RMI 接口(interface)的方法上对其进行建模。 Spring代理接口(interface)生成RmiInvocationWrapper对于非 RMI 方法的调用,序列化方法细节和参数,然后在 RMI 连接的远端调用它。

  • 使用 ProxyFactory和一个 RmiInvocationHandler代理目标对象的实现。
  • 使用 RmiBasedExporter 的新实现至 getObjectToExport() , 并使用 UnicastRemoteObject#export(obj, 0) 将其导出.
  • 对于调用处理程序,rmiInvocationHandler.invoke(invocationFactory.createRemoteInvocation(invocation)) , 与 DefaultRemoteInvocationFactory .
  • 处理异常并适当换行以避免看到 UndeclaredThrowableException s.

因此,我们可以使用 RMI 导出任意对象。这意味着我们可以在客户端使用这些对象之一作为 RMI 服务器端对象上的 RMI 方法调用的参数,并且当服务器端的反序列化 stub 调用方法时,这些方法将在客户端。魔法。

关于java - 从服务器在客户端执行的 spring 双向 rmi 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3779134/

相关文章:

php - 从网络客户端访问 REST API 的最佳方式是什么?

java - 重构这个递归方法?

java - Intellij : how to add java. javax.annotation.PostConstruct 注释模块

java - 在 Spring 配置中初始化空数组列表?

java - 没有类型为“org.springframework.data.jpa.repository.support.JpaEntityInformation”的合格 bean

java - 尝试从 Spring Boot 创建 SWING/AWT 框架时由 : java. awt.HeadlessException 引起

docker - Docker 中的 WSL2 Caddy 反向代理

java - 如何在 Windows 中使用带代理的 weka 包管理器?

java - SQLite数据库错误: table has no column name

java - Imageview 不采用卡片 View 的角半径