Экземпляр какого класса создается при инстанцировании обычного Spring-компонента?

Ответ

Spring создает прокси-объект, а не экземпляр исходного класса. Тип прокси зависит от конфигурации компонента:

  1. CGLIB-прокси (по умолчанию): Создается подкласс исходного класса.

    @Component
    public class MyService { /* ... */ }
    // При вызове getBean("myService") вернется объект типа:
    // class MyService$$EnhancerBySpringCGLIB$$...
  2. JDK Dynamic Proxy: Если компонент реализует хотя бы один интерфейс и настроено проксирование через интерфейсы (proxyMode = ScopedProxyMode.INTERFACES).

    @Component
    public class MyServiceImpl implements MyService { /* ... */ }
    // Будет возвращен прокси типа: com.sun.proxy.$ProxyXX

Почему так? Проксирование необходимо для прозрачного добавления сквозной функциональности (AOP), такой как транзакции (@Transactional), кэширование (@Cacheable) или безопасность.

Ответ 18+ 🔞

А, ну это классика, блядь! Вечная путаница, как в бабушкином комоде. Сейчас разложу по полочкам, чтобы ты не пиздел, что ничего не понял.

Смотри, Spring — он как хитрая жопа, которая любит подсунуть тебе не то, что ты просил, а то, что ему удобнее. Ты думаешь, ты получаешь свой честный MyService? Ага, щас, держи карман шире! На самом деле тебе впаривают прокси-объект, сука, подделку!

А тип этой подделки зависит от того, как ты свою хрень настроил:

  1. CGLIB-прокси (дефолтный, как госпошлина). Spring тупо наследуется от твоего класса и делает подкласс. Как будто твой MyService родил уебка с длинным именем.

    @Component
    public class MyService { /* ... */ }
    // Вызываешь getBean("myService"), а тебе подсовывают:
    // class MyService$$EnhancerBySpringCGLIB$$... (какой-то мутант, блядь)
  2. JDK Dynamic Proxy (для интеллигентных, с интерфейсами). Включается, если твой компонент реализует хоть один интерфейс и ты явно сказал: "Хочу через интерфейсы, ёпта!" (proxyMode = ScopedProxyMode.INTERFACES).

    @Component
    public class MyServiceImpl implements MyService { /* ... */ }
    // Получаешь уже не мутанта, а стандартную шлюху от Java:
    // com.sun.proxy.$ProxyXX (какой-то номерок, как в борделе)

А нахуя это всё, спросишь? Да затем, сука, чтобы можно было незаметно, как вор в ночи, накрутить вокруг твоего кода всякую сквозную хуйню! Транзакции (@Transactional), кэширование (@Cacheable), безопасность — всё это цепляется через эти прокси. Без них Spring был бы просто тупым фабричным статиком, а так — волшебник, блядь, ёперный театр!

Вот и весь расклад. Не благодари.