我想了解动态代理存根实现实际上是如何在幕后完成的。根据我阅读的内容,如果没有找到预先生成的存根类,则在导出远程对象时,RMI 运行时将生成一个动态代理来充当存根。然后将该存根绑定到 RMI 注册表,然后由某些 RMI 客户端访问。
问题是:既然存根实际上是一个动态生成的代理,它的类定义在客户端是不可用的,那么为什么客户端仍然能够从 RMI Registry 中检索存根呢?幕后是否发生了某种动态类加载,或者 RMI 是否使用另一种技术来解决这个问题?
我想了解动态代理存根实现实际上是如何在幕后完成的。根据我阅读的内容,如果没有找到预先生成的存根类,则在导出远程对象时,RMI 运行时将生成一个动态代理来充当存根。然后将该存根绑定到 RMI 注册表,然后由某些 RMI 客户端访问。
问题是:既然存根实际上是一个动态生成的代理,它的类定义在客户端是不可用的,那么为什么客户端仍然能够从 RMI Registry 中检索存根呢?幕后是否发生了某种动态类加载,或者 RMI 是否使用另一种技术来解决这个问题?
Java.lang.reflect.Proxy 是可序列化的,它在 ObjectOutputStream 和 ObjectInputStream 中有特殊的支持。基本上只是实现的接口和调用处理程序被序列化,并且在反序列化期间从中构造一个新的动态代理。
RMI 确实使用动态类加载——类路径与调用一起作为客户端加载类的“类路径注释”发送。您可以查看 RMI 实现以获取更多信息 - 它作为 JDK 源代码的一部分提供。具体来说,ObjectOutputStream 和 RMIClassloader 类。
更新:RMI 不会启动 HTTP 服务器 - 事实上,您需要为此定制解决方案。您提到的其中一个可以是您运行的 HTTP 服务器,通过服务器使类可用,并在您的存根中使用 HTTP 服务器的地址/端口传递代码库,以便您的客户端可以下载它们。