AnnotationConfigApplicationContext是Spring用来加载注解配置的ApplicationContext,它是如何加载所有的bean,与ClassPathXmlApplicationContext有什么区别,让我们接下来揭开它的神秘面纱。
类图
AnnotationConfigApplicationContext
这里我们拿AnnotationConfigApplicationContext与ClassPathXmlApplicationContext对比,由一、spring ioc之ClassPathXmlApplicationContext源码解析我们知道,ClassPathXmlApplicationContext加载bean的逻辑是在AbstractRefreshableApplicationContext的refreshBeanFactory()方法中,但是我们从类图中可以看出,AnnotationConfigApplicationContext并没有实现这个类,那么它是如何加载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);
}
无参构造函数中主要是初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner两个类。这里主要关注AnnotatedBeanDefinitionReader,跟踪这个类的初始化发现它会注册一堆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加载也调用了它,但是ClassPathXmlApplicationContext在调用obtainFreshBeanFactory()的时候就把所有的bean加载完成,但是AnnotationConfigApplicationContext并没有继承自AbstractRefreshableApplicationContext,所以在obtainFreshBeanFactory()这步还是没有加载bean。真正加载bean的操作是在invokeBeanFactoryPostProcessors(beanFactory),这个方法调用所有实现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;
}
调用逻辑
AbstractApplicationContext#refresh()中调用了invokeBeanFactoryPostProcessors(beanFactory);这个方法逻辑如下:
- 遍历所有实现了BeanDefinitionRegistryPostProcessor接口的bean
- 调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry
- 调用实现了Ordered接口的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry
- 调用普通的BeanDefinitionRegistryPostProcessors(没有实现Ordered接口和PriorityOrdered接口)的postProcessBeanDefinitionRegistry
- 遍历所有实现BeanFactoryPostProcessor接口的bean,剩下的操作和BeanDefinitionRegistryPostProcessors的处理逻辑是一样的。