XML 中 <context:component-scan base-package="..."/> 觸發 ContextNamespaceHandler,其 init() 註冊 ComponentScanBeanDefinitionParser。
ClassPathBeanDefinitionScanner(繼承 ClassPathScanningCandidateComponentProvider)。@Component、@ManagedBean、@Named 及其衍生註解。base-package,構造掃描模式 classpath*:com/pkg/**/*.class。AnnotationMetadata。includeFilters/excludeFilters 篩選候選類別。ScannedGenericBeanDefinition(含 AnnotationMetadata),設定 beanClass、resource、source 等屬性。BeanDefinitionDefaults、解析 @Lazy、@Primary、@DependsOn、@Role 等註解屬性。BeanDefinitionRegistry,發送 ReaderEventListener 事件。掃描結束時自動註冊:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor。
不同於 XML/Annotation 的預先解析,Java Config 由 ConfigurationClassPostProcessor(實作 BeanDefinitionRegistryPostProcessor)在 所有 BeanDefinition 已載入註冊表後、實例化前 介入處理。
@Component 或 @Configuration 標註的 BeanDefinition,解析其 @Bean 方法,封裝為 BeanMethod,建立類別層級的 ConfigurationClass 模型。ConfigurationClass,將每個 BeanMethod 轉換為 ConfigurationClassBeanDefinition(繼承 RootBeanDefinition,含 AnnotationMetadata),設定 factoryMethodName、initMethodName、destroyMethodName、autowireMode 等,並註冊至 Registry。| 配置方式 | BeanDefinition 具體類型 | 解析時機 |
|---|---|---|
| XML | GenericBeanDefinition | 容器啟動初期,預先解析 |
| Annotation | ScannedGenericBeanDefinition | 容器啟動初期,預先解析 |
| Java Config | ConfigurationClassBeanDefinition | BeanDefinitionRegistryPostProcessor 階段,延後解析 |
| 維度 | XML | Annotation | Java Config |
|---|---|---|---|
| 集中管理 | ✓ 集中 | ✗ 分散 | ✓ 集中於 @Configuration 類 |
| 修改重編譯 | ✗ 不需 | ✓ 需 | ✓ 需 |
| 型別安全 | ✗ | △ | ✓ 編譯期檢查 |
| 重構友善 | ✗ | △ | ✓ IDE 重構支援 |
| 表達力 | 基本 | 基本 | 完整 Java 語言能力 |
Spring 3.2 透過 NamespaceHandler/BeanDefinitionParser 處理 XML 與 Annotation,透過 BeanDefinitionRegistryPostProcessor 機制優雅地引入 Java Config 延後解析模式,三者共存互補,開發團隊可根據專案規模、團隊習慣與維護策略選擇適配組合。