Какой артефакт или метаданные обрабатываются во время компиляции Spring-приложения перед созданием BeanDefinition?

Ответ

Непосредственно перед созданием BeanDefinition на этапе обработки аннотаций (во время компиляции или загрузки класса) Spring работает с AnnotationMetadata.

Процесс и ключевые артефакты:

  1. Чтение класса: Spring (через ClassPathScanningCandidateComponentProvider) считывает байт-код класса.
  2. Получение метаданных: Для класса извлекается ClassMetadata (информация о классе) и, что важнее, AnnotationMetadata.
    • AnnotationMetadata содержит информацию обо всех аннотациях класса (например, @Component, @Service, @Scope, @Lazy).
  3. Анализ аннотаций: На основе AnnotationMetadata Spring определяет, является ли класс кандидатом на создание бина, его scope, lazy-инициализацию и другие атрибуты.
  4. Создание BeanDefinition: Только после этого анализа создается объект BeanDefinition (например, ScannedGenericBeanDefinition), который инкапсулирует эти метаданные для последующего использования IoC-контейнером при создании экземпляров бинов.

Наглядный пример: Для класса:

@Service
@Lazy
@Scope("prototype")
public class OrderService {
    // ...
}

Во время обработки Spring сначала получит AnnotationMetadata, содержащее данные об аннотациях @Service, @Lazy и @Scope. На основе этих данных будет построен BeanDefinition, у которого будут установлены флаги: lazyInit = true, scope = "prototype".

Техническая деталь: В современных Spring-приложениях (особенно с Spring Boot) эта обработка часто происходит не во время компиляции javac, а во время загрузки классов JVM или с помощью пост-процессоров (как ConfigurationClassPostProcessor), которые читают аннотации и регистрируют BeanDefinition в BeanFactory. Ключевой ввод — это именно метаданные аннотаций (AnnotationMetadata).

Ответ 18+ 🔞

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

Вот представь себе: Spring — это такой дотошный таможенник на границе твоего приложения. И пока ты, довольный, пишешь @Service над своим классом OrderService, он уже начинает свою подлую работу.

Как это происходит, по-человечески:

  1. Всё начинается с обыска. Не с создания бина, нет! Сначала контейнер, через своих шпионов (типа ClassPathScanningCandidateComponentProvider), выкатывает сканер и начинает рыться в байт-коде твоих классов. Читает, сука, как книжку.

  2. Выуживает компромат. И главное, что его интересует — это AnnotationMetadata. Это, блядь, такая папочка с досье, где собрано всё: где ты @Component повесил, где @Service прилепил, не @Lazy ли ты случаем, и в каком @Scope тусуешься — singleton или prototype.

  3. Принимает решение. Только ПОСЛЕ того, как он изучил это досье (AnnotationMetadata), он решает: "Ага, этот чувак — кандидат в бины". И вот тут-то, наконец, рождается BeanDefinition — уже как официальная инструкция для фабрики: "Создай объект, делай его ленивым (lazyInit=true), и пусть у каждого будет своя отдельная копия (scope="prototype")".

  4. Техническая подстава. Важный момент, чтобы не обосраться: вся эта магия с чтением аннотаций происходит не когда ты компилируешь код (это было бы слишком просто), а позже — во время загрузки классов JVM или благодаря специальным засланным казачкам — пост-процессорам (вроде ConfigurationClassPostProcessor). Они тихой сапой пробираются, читают твои @Service и @Lazy, и шепчут на ухо BeanFactory, кого и как регистрировать.

Простой пример, чтобы вообще всё стало ясно:

Вот твой класс, красавец:

@Service
@Lazy
@Scope("prototype")
public class OrderService {
    // ...
}

Что делает Spring?

  • Видит класс. Вытаскивает из него AnnotationMetadata — пачку аннотаций.
  • Читает: "Ага, @Service — значит, бин. @Lazy — значит, не создавай, пока не прижмёт. @Scope("prototype") — значит, на каждый запрос новый экземпляр, а не один на всех, как жмот".
  • И только потом формирует BeanDefinition с этими настройками. Эта штука — уже не аннотации, а конкретный план действий для контейнера.

Короче, запомни: сначала AnnotationMetadata (досье), потом BeanDefinition (приказ). Без этого досье Spring — как слепой котёнок, нихуя не понимает, что делать с твоим классом.