AnnotationConfigApplicationContext是Spring用來加載注解配置的ApplicationContext,它是如何加載所有的bean,與ClassPathXmlApplicationContext有什么區(qū)別,讓我們接下來揭開它的神秘面紗。
類圖

AnnotationConfigApplicationContext
這里我們拿AnnotationConfigApplicationContext與ClassPathXmlApplicationContext對比,由一、spring ioc之ClassPathXmlApplicationContext源碼解析我們知道,ClassPathXmlApplicationContext加載bean的邏輯是在AbstractRefreshableApplicationContext的refreshBeanFactory()方法中,但是我們從類圖中可以看出,AnnotationConfigApplicationContext并沒有實現(xiàn)這個類,那么它是如何加載bean的呢?
初始化
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
- this()
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
無參構(gòu)造函數(shù)中主要是初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner兩個類。這里主要關注AnnotatedBeanDefinitionReader,跟蹤這個類的初始化發(fā)現(xiàn)它會注冊一堆BeanFactoryPostProcessor處理器,我們只需關注ConfigurationClassPostProcessor。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
...
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
...
}
- register(annotatedClasses)
這個方法主要是把所有的配置類注冊成bean。 - refresh()
一個很熟悉的方法,因為ClassPathXmlApplicationContext加載也調(diào)用了它,但是ClassPathXmlApplicationContext在調(diào)用obtainFreshBeanFactory()的時候就把所有的bean加載完成,但是AnnotationConfigApplicationContext并沒有繼承自AbstractRefreshableApplicationContext,所以在obtainFreshBeanFactory()這步還是沒有加載bean。真正加載bean的操作是在invokeBeanFactoryPostProcessors(beanFactory),這個方法調(diào)用所有實現(xiàn)BeanFactoryPostProcessor接口的bean。那么BeanFactoryPostProcessor又是干嘛的呢?
BeanFactoryPostProcessor處理器
和BeanPostProcessor原理一致,Spring提供了對BeanFactory進行操作的處理器BeanFactoryProcessor,簡單來說就是獲取容器BeanFactory,這樣就可以在真正初始化bean之前對bean做一些處理操作。BeanFactoryProcessor定義如下:
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子類,也只要一個方法
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
調(diào)用邏輯
AbstractApplicationContext#refresh()中調(diào)用了invokeBeanFactoryPostProcessors(beanFactory);這個方法邏輯如下:
- 遍歷所有實現(xiàn)了BeanDefinitionRegistryPostProcessor接口的bean
- 調(diào)用實現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry
- 調(diào)用實現(xiàn)了Ordered接口的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry
- 調(diào)用普通的BeanDefinitionRegistryPostProcessors(沒有實現(xiàn)Ordered接口和PriorityOrdered接口)的postProcessBeanDefinitionRegistry
- 遍歷所有實現(xiàn)BeanFactoryPostProcessor接口的bean,剩下的操作和BeanDefinitionRegistryPostProcessors的處理邏輯是一樣的。