上一节展示了BeanFactory的初始化过程,其主要任务是载入BeanDefinition并通过BeanDefinition初始化bean保存在singletonObjects中。
那么ApplicationContext的任务是什么呢?BeanDefinition的生成并不是由BeanFactory完成的,而是由ApplicationContext相关类完成的。
当我们使用spring boot进行开发时,由于省去了xml配置文件, 项目启动时默认采用的AnnotationConfigEmbeddedWebApplicationContext,其定义如下:
public class AnnotationConfigEmbeddedWebApplicationContext extends EmbeddedWebApplicationContext {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
private Class<?>[] annotatedClasses;
private String[] basePackages;
AnnotationConfigEmbeddedWebApplicationContext有四个十分重要的属性,AnnotatedBeanDefinitionReader 类型的reader用于生成BeanDifinition,ClassPathBeanDefinitionScanner类型的scanner用于完成扫描的工作,annotatedClasses则存储扫描的类,basePackages是指定要扫描的包。
不同多说,上述四个属性的定义基本为我们揭示了创建BeanDifinition的过程。
另外,AnnotationConfigEmbeddedWebApplicationContext继承的GenericApplicationContext类含有DefaultListableBeanFactory的对象,因此可以认为,Spring boot应用只将ApplicationContext暴露在外,而具体创建类等工作都是在ApplicationContext内部完成的。
顺便一提,AnnotationConfigEmbeddedWebApplicationContext是通过最基本的SpringsourceApplication初始化实现的:
//Main函数
public static void main(String[] args) {
SpringApplication.run(XXX.class, args);
}
//SpringApplication中的run方法:
public ConfigurableApplicationContext run(String... args) {
...
ConfigurableApplicationContext context = null;
...
try {
...
context = this.createApplicationContext();
...
}
//SpringApplication中的createApplicationContext方法:
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if(contextClass == null) {
try {
contextClass = Class.forName(this.webEnvironment?"org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext":"org.springframework.context.annotation.AnnotationConfigApplicationContext");
} catch (ClassNotFoundException var3) {
throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
}
}
return (ConfigurableApplicationContext)BeanUtils.instantiate(contextClass);
}
最后,在完成AnnotationConfigEmbeddedWebApplicationContext的创建后,会调用EmbeddedWebApplicationContext的refresh()方法,该方法会一直调用到DefaultListableBeanFactory的getBean方法,这样就回到上一节的内容了。
总的来说,ApplicationContext的功能就到这里了,
在Spring boot刚启动时,会创建ApplicationContext,而ApplicationContext内部又会初始化BeanFactory,然后,ApplicationContext完成扫描包并生成BeanDefinition的过程,将BeanDefinition注册到(register)BeanFactory中。