Получить доступ

Когда Spring создаёт JDK dynamic proxy, а когда CGLIB-прокси?

MiddleAOP и проксиSpringSpring Boot
Ещё спрашивают так:
  • Почему Spring Boot использует CGLIB-прокси?
Коротко

JDK dynamic proxy — реализует интерфейсы бина, перехватывает только методы интерфейсов. CGLIB — подкласс бина, работает без интерфейсов. Spring Boot по умолчанию включает CGLIB (proxyTargetClass=true).

  • С JDK-прокси бин нельзя внедрить по типу класса — только по интерфейсу
  • CGLIB не перехватывает final-методы и не работает с final-классами
  • Начиная с Spring 4, конструктор вызывается один раз (Objenesis)

А ещё Kotlin-классы final по умолчанию — нужен плагин kotlin-spring

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

JDK-прокси реализует те же интерфейсы, что и целевой бин, поэтому внедрять такой бин можно только по интерфейсу — попытка внедрить по конкретному классу даст ошибку приведения типа. Именно из-за этой неприятности Spring Boot по умолчанию включает proxyTargetClass и использует CGLIB, который создаёт подкласс и потому совместим с обоими вариантами внедрения. Цена CGLIB — невозможность проксировать final-классы и final-методы, а также то, что конструктор целевого класса вызывается дважды в старых версиях. Знание, что умолчание в Boot отличается от умолчания в чистом Spring Framework, ценится на собеседовании.

Что хотят услышать

  • Механизм каждого вида.
  • Выбор по умолчанию в Spring и Boot.
  • Ограничения.

Частые ошибки

  • Считать, что при наличии интерфейса всегда будет JDK-прокси — в Spring Boot это не так.
  • Делать класс с @Transactional final.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓JDK-прокси — когда бин реализует интерфейсы и не форсирован proxyTargetClass; иначе создаётся CGLIB-подкласс. В Spring Boot по умолчанию используется CGLIB
  • ✗Всегда используется JDK dynamic proxy, CGLIB давно удалён
  • ✗Выбор зависит от того, есть ли у класса конструктор без аргументов
  • ✗CGLIB применяется только для final-классов

Что спросят дальше

  • Почему бин за JDK-прокси нельзя внедрить по классу?
  • Что произойдёт с @Transactional на final-методе?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем