Как заставить Byte Buddy загружать много типов в один и тот же загрузчик классов-оболочек - PullRequest
1 голос
/ 05 апреля 2019

Я использую 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();

Но это не похоже на стратегию clean для меня, учитывая, что она, кажется, вводит с помощью самоанализа, чтобы обойти тот факт, что загрузчик классов запечатан.Поэтому мне интересно, есть ли лучший механизм для этого в Byte Buddy.

Обратите внимание, что для того, чтобы иметь правильно запечатанный загрузчик класса , я мог бы превратить все свои многие тысячи DynamicType.Unloadedобъекты в Class<?> сразу в один экземпляр загрузчика классов (и запечатать его).Я могу инициализировать все свои классы при загрузке приложения в пакете, а затем оставить загрузчик классов в покое без дальнейшего создания динамического класса.

Какова будет правильная стратегия для сценария, подобного моему?

1 Ответ

1 голос
/ 05 апреля 2019

Загрузчик классов, который создается при использовании стратегии WRAPPER, позволяет загружать классы позднее в жизненном цикле загрузчика классов. По соображениям безопасности это необходимо включить, вызвав opened() для стратегии.

Затем вы можете преобразовать загрузчик первого класса в InjectionClassLoader, что позволяет использовать InjectionClassLoader.Strategy.INSTANCE, где дополнительные классы могут быть внедрены без какого-либо небезопасного API.

Вы также можете объединить несколько экземпляров DynamicType, вызвав include, а затем загрузить все классы, используя WRAPPER за одну стирку.

...