Что быстрее, динамический прокси JDK или CGLib в Spring AOP?

Java задняя часть .NET Spring

1. Предпосылки

Вчера у небольшого партнера «Планеты знаний» во время интервью спросили: что эффективнее, динамический прокси-сервер JDK или CGLib в Spring AOP? Я разобрался с этим на Планете Знаний и поделился сегодня для вашего ознакомления! Если вас интересует Планета знаний, вы можете узнать о:

2. Основные понятия

Прежде всего, мы знаем, что существует два способа базовой реализации Spring AOP: один — это динамический прокси-сервер JDK, а другой — способ CGLib.

Начиная с Java 1.3, Java предоставляет динамическую прокси-технологию, которая позволяет разработчикам создавать прокси-экземпляры интерфейсов во время выполнения, и с тех пор эта технология во многих местах используется в Spring.

Динамический прокси-сервер JDK в основном включает два класса в пакете java.lang.reflect: Proxy и InvocationHandler. Среди них InvocationHandler — это интерфейс, который может определять сквозную логику путем реализации этого интерфейса и вызывать код целевого класса через механизм отражения для динамического объединения сквозной логики и бизнес-логики.

У динамического прокси JDK есть ограничение, то есть он может создавать экземпляры прокси только для интерфейсов, а как создавать экземпляры динамических прокси для классов, которые не определяют бизнес-методы через интерфейсы? Ответ: CGLib.

CGLib использует базовую технологию байт-кода, полное название: библиотека генерации кода, CGLib может создавать подкласс для класса, использовать технологию перехвата методов в подклассе для перехвата всех вызовов методов родительского класса и вплетать сквозную логику в тренд.

3. Разница между динамическим прокси JDK и CGLib

1. Конкретный принцип реализации динамического прокси JDK:

  • Создайте свой собственный обработчик вызова, реализовав интерфейс InvocationHandler;

  • Создайте динамический прокси, указав объект ClassLoader и набор интерфейсов для класса Proxy;

  • Конструктор динамического прокси-класса получается через механизм отражения, и его единственным типом параметра является тип интерфейса вызывающего процессора;

  • Создайте экземпляр динамического прокси-класса через конструктор и вызовите объект-процессор в качестве параметра во время построения;

Динамический прокси-сервер JDK – это интерфейсно-ориентированный режим прокси-сервера. Если целевой прокси-сервер не имеет интерфейса, то Spring ничего не может сделать. Spring создает новый анонимный класс реализации прокси-интерфейса с помощью механизма отражения Java и переписывает расширение АОП. метод.

2. Динамический прокси CGLib:

CGLib — это мощная и высокопроизводительная библиотека классов для создания кода, которая может динамически расширять классы Java во время выполнения. Spring наследует классы для динамического проксирования через CGlib во время выполнения, переписывает методы родительского класса и реализует АОП-ориентированное программирование.

3. Сравнение двух:

  • Динамические прокси JDK ориентированы на интерфейс.

  • Динамический прокси CGLib реализуется путем подкласса класса прокси в нижней части байт-кода (если класс прокси изменен с ключевым словом final, это не удастся, извините).

4. Примечания по использованию:

  • Если проксируемый объект является классом реализации, то Spring будет использовать динамический прокси-сервер JDK для завершения операции (по умолчанию Spirng использует механизм реализации динамического прокси-сервера JDK);

  • Если проксируемый объект не является классом реализации, Spring заставит использовать CGLib для реализации динамических прокси.

Четыре, сравнение производительности динамических прокси JDK и CGLib — описание в учебнике

Читаем ли мы книги или статьи или ищем справочные ответы на моем веб-сайте, мы можем много раз находить следующие ответы:

Что касается производительности между ними, производительность прокси-объекта, созданного динамическим прокси-сервером JDK, не очень высока в предыдущей версии JDK.Хотя производительность динамического прокси-объекта JDK была значительно улучшена в старшей версии, но это также подходит не для всех сценариев. В основном это отражается в следующих двух показателях:

1. Производительность динамического прокси-объекта, созданного CGLib, намного выше, чем у динамического прокси JDK в реальном времени выполнения, некоторые исследования показали, что она примерно в 10 раз выше;

2. Однако время, затрачиваемое CGLib на создание объектов, намного больше, чем у динамического прокси JDK.Некоторые исследования показали, что существует разрыв примерно в 8 раз;

3. Поэтому для одноэлементных прокси-объектов или прокси с пулами экземпляров удобнее использовать динамический прокси CGLib, так как нет необходимости часто создавать прокси-объекты, в любом случае больше подходит динамический прокси JDK.

Результат такой, как описано в пунктах 1, 2 и 3 выше? Ниже мы проведем несколько небольших экспериментов для анализа!

5. Тест производительности

1. Во-первых, есть несколько классов Java

2. Цель.java

3. TargetImpl.java

4. JdkDynamicProxyTest.java

5. CglibProxyTest.java

6. ProxyPerformanceTest.java

7. Результаты испытаний

(1) ДДК 1.6

(2) ДДК 1.7

(3) ДДК 1.8

После многих тестов видно, что в среднем скорость работы динамического прокси JDK постепенно улучшалась.В низкой версии производительность может быть не такой хорошей, как у CGLib, но после многократного запуска в версии 1.8 вы в основном может получить Согласованный результат теста заключается в том, что динамический прокси JDK уже быстрее, чем динамический прокси CGLib!

Однако применимые сценарии динамического прокси-сервера JDK и динамического прокси-сервера CGLib по-прежнему различаются!

6. Резюме

Окончательные результаты тестов примерно таковы.В версиях 1.6 и 1.7 скорость динамического прокси JDK ниже, чем у динамического прокси CGLib, но в учебниках нет разрыва в 10 раз.В JDK1.8, динамический прокси JDK скорость прокси-сервер намного быстрее, чем у динамического прокси-сервера CGLib.Я надеюсь, что мои друзья могут стать целью, когда они столкнутся с этой проблемой!

Динамический прокси JDK и CGLib в Spring AOP очень важен для этой точки зрения. Сравнение производительности между ними уже дало предварительный результат после тестового эксперимента. Если кто-то спросит вас о Spring AOP в будущем, не просто скажем JDK динамический прокси И эти два CGLib, пора выкинуть понимание разницы между ними, есть бонус!

Справочная статья:

1. https://blog.csdn.net/qq1723205668/article/details/56481476 2. https://blog.csdn.net/xiangbq/article/details/49794335

Нажмите на изображение, чтобы увидеть больше рекомендуемого контента

↓↓↓

Расскажу вам 38 советов по базе данных MySQL!

Динамический прокси кидает хлыст и отсекает поток! Взгляните на основной принцип реализации MyBatis!

Пугающий исходный код, на что мне смотреть?

Как быть надежным программистом!