Ответ
Непосредственно перед созданием BeanDefinition на этапе обработки аннотаций (во время компиляции или загрузки класса) Spring работает с AnnotationMetadata.
Процесс и ключевые артефакты:
- Чтение класса: Spring (через
ClassPathScanningCandidateComponentProvider) считывает байт-код класса. - Получение метаданных: Для класса извлекается
ClassMetadata(информация о классе) и, что важнее,AnnotationMetadata.AnnotationMetadataсодержит информацию обо всех аннотациях класса (например,@Component,@Service,@Scope,@Lazy).
- Анализ аннотаций: На основе
AnnotationMetadataSpring определяет, является ли класс кандидатом на создание бина, его scope, lazy-инициализацию и другие атрибуты. - Создание 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).