Java:(部分)类的序列化(不是对象!)

标签 java serialization classloader

我目前正在执行一项任务,将组件及其依赖项打包在一起,并从中创建一个独立的组件,其中包含所有需要的内容。

我遇到的情况是,我可能也需要将用户定义的类包含在该组件中。

我正在寻找一种以 slim /智能的方式序列化它们的方法。例如,这些类具有继承层次结构:

FrameWorkSuper
--------------
UserSuper 
UserClass

有没有办法只序列化类的用户定义部分以保持较小的占用空间?任何源自框架的内容都肯定包含在最终的组件中。因此,我想序列化并稍后仅加载整体的用户定义部分,以便类获取框架部分也在包中。

有没有办法实现这个目标,或者有什么建议可以让我完成这个任务?

最佳答案

我认为您想要做的是传输用户定义类的实际字节码。

  1. 如果您没有类的字节码而只有源代码,则需要先编译它。我建议使用JavaCompiler
    • 由于将所有内容编译到磁盘然后再次将其读取到字节数组有点繁琐,因此您可能需要使用自己的 FileManager 和 JavaFileObject 实现,如有必要,我可以提供有关此步骤的详细信息。
  2. 获得类的字节代码后,将其发送到您想要的任何位置(文件、数据库、远程站点)。
  3. 当“反序列化”时(正如其他人指出的,序列化并不是真正正确的术语),从您拥有的任何地方加载字节代码。
  4. 创建一个自定义类加载器,它获取所有类的字节码并将其 findClass 方法重写为类似的内容

    // first try our cache of loaded classes
    if (loadedClasses.containsKey(name)) {
        return loadedClasses.get(name);
    }
    
    // that didn't work, maybe the class was compiled but not yet loaded
    if (compiledClasses.containsKey(name)) {
        // get the representation from the cache
        InMemoryClassJavaFileObject inMemoryRepresentation = compiledClasses.get(name);
        // let our parent define the class
        Class<?> clazz = defineClass(name, inMemoryRepresentation.getData(), 0, inMemoryRepresentation.getData().length);
        // and store it in the cache for later retrieval
        loadedClasses.put(name, clazz);
        return clazz;
    }
    

    请注意,您不需要创建 InMemoryClassJavaFileObject,只需使用字节数组即可。

  5. 要实现上述目标,您将需要从类的字节码中获取类的完全限定名称。单独提供该信息或使用 this method

这使您可以访问远程站点上的类本身:您可以创建实例并使用它们的方法。

关于Java:(部分)类的序列化(不是对象!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27419908/

相关文章:

java - 使用类加载器在 java 程序中运行可执行 jar 文件

java - 序列化对象仅打印最后一个

c# - 包括具有序列化形式的数组 - jquery

java - WAR 类访问其他 WAR 中的另一个类

java - 从 Controller 内部访问 Magnolia TemplatedFunctions

java - java中的归并排序

java - 什么时候字符串在Java中是不同的对象?

java - 套接字重置异常 - Java

java - 使用gson解析Json

java - java中的类卸载