Когда Spring создаёт JDK dynamic proxy, а когда CGLIB-прокси?
- Почему Spring Boot использует CGLIB-прокси?
JDK dynamic proxy — реализует интерфейсы бина, перехватывает только методы интерфейсов. CGLIB — подкласс бина, работает без интерфейсов. Spring Boot по умолчанию включает CGLIB (proxyTargetClass=true).
- С JDK-прокси бин нельзя внедрить по типу класса — только по интерфейсу
- CGLIB не перехватывает final-методы и не работает с final-классами
- Начиная с Spring 4, конструктор вызывается один раз (Objenesis)
А ещё Kotlin-классы final по умолчанию — нужен плагин kotlin-spring
Подробно
JDK-прокси реализует те же интерфейсы, что и целевой бин, поэтому внедрять такой бин можно только по интерфейсу — попытка внедрить по конкретному классу даст ошибку приведения типа. Именно из-за этой неприятности Spring Boot по умолчанию включает proxyTargetClass и использует CGLIB, который создаёт подкласс и потому совместим с обоими вариантами внедрения. Цена CGLIB — невозможность проксировать final-классы и final-методы, а также то, что конструктор целевого класса вызывается дважды в старых версиях. Знание, что умолчание в Boot отличается от умолчания в чистом Spring Framework, ценится на собеседовании.
Что хотят услышать
- Механизм каждого вида.
- Выбор по умолчанию в Spring и Boot.
- Ограничения.
Частые ошибки
- Считать, что при наличии интерфейса всегда будет JDK-прокси — в Spring Boot это не так.
- Делать класс с @Transactional final.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Всегда используется JDK dynamic proxy, а CGLIB удалён из Spring ещё в пятой версии
- ✗Выбор зависит от того, есть ли у класса конструктор без аргументов
- ✓JDK-прокси — если бин реализует интерфейсы, иначе CGLIB; в Boot по умолчанию CGLIB
- ✗CGLIB применяется только для final-классов
Что спросят дальше
- Почему бин за JDK-прокси нельзя внедрить по классу?
- Что произойдёт с @Transactional на final-методе?
Разбор темы
- AOP: прокси и аспекты
Сквозная функциональность, понятия aspect/advice/pointcut/join point, JDK против CGLIB прокси, self-invocation и что на AOP построено.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.