如何使Byte Buddy将许多类型加载到同一个包装类加载器中

问题描述 投票:1回答:1

我正在使用Byte Buddy,我可能需要用它来创建几十万个类。这些是实现接口的独立类,而不是代理。

现在我通过包装我的应用程序的类加载器将我的DynamicType.Unloaded<?>实例加载到类加载器中:

final Class<?> myClass =
    unloadedType
        .load(someAppClassLoader, ClassLoadingStrategy.Default.WRAPPER)
        .getLoaded();

这个包装策略适合我,但我有一个问题,每次我执行上面的代码时,创建一个新的,密封的ClassLoader只包含新类。我知道我可以“包含”辅助类型......但这些不是辅助类型,而是完全独立的类。

因为我需要创建数千个,所以我留下了大量的类加载器,我并不需要它,因为我想将其余的bytebuddy创建的类隔离开来,而不是从另一个中隔离出来,也没有任何需要为每个人创建一个新的类加载器。我的分析显示了大量类加载器(在这种情况下非常繁重)的巨大内存开销。

从我的测试看来,我可以使用第一个包装策略:

final Class<?> myClass =
    type
        .load(someAppClassLoader, ClassLoadingStrategy.Default.WRAPPER)
        .getLoaded();

...然后检索新的类加载器:

final ClassLoader bbClassLoader = myClass.getClassLoader();

...然后通过将策略切换到注入,在后续创建中使用此类加载器:

final Class<?> myOtherClass =
    otherUnloadedType
        .load(bbClassLoader, ClassLoadingStrategy.Default.INJECTION)
        .getLoaded();

但这似乎不是一个干净的策略,因为它似乎是通过内省注入,以避免类加载器被密封的事实。所以我想知道在Byte Buddy中是否有更好的机制。

请注意,为了拥有一个正确密封的类加载器,我可以将所有数千个DynamicType.Unloaded对象一次性转换为Class<?>对象到一个类加载器实例中(并密封它)。我可以批量初始化应用程序引导程序中的所有类,然后单独保留类加载器,而无需进一步创建动态类。

对于像我这样的场景,适当的策略是什么?

java classloader introspection byte-buddy bytecode-manipulation
1个回答
1
投票

使用WRAPPER策略时创建的类加载器允许稍后在类加载器的生命周期中加载类。出于安全原因,需要通过在策略上调用opened()来启用此功能。

然后,您可以将第一个类加载器强制转换为InjectionClassLoader,这允许使用InjectionClassLoader.Strategy.INSTANCE,其中可以在没有任何不安全API的情况下注入其他类。

您还可以通过调用DynamicType组合多个include实例,然后在一次清洗中使用WRAPPER加载所有类。

© www.soinside.com 2019 - 2024. All rights reserved.