一、创建一个ApplicationContext实例,即我们常说的IoC容器
ApplicationContext context = createApplicationContext();
二、向IoC容器中,注册源配置类
源配置类:通常是main方法所在的类,而且会被SpringBootApplication注解所修饰,又称为主类
loadSourceClass(context, primaryClass);
三、递归加载并处理所有的配置类
public static void processConfigurationClasses(ApplicationContext context){
//1.首先从IoC容器中取出当前存在的源配置类
Class<?> sourceConfigurationClass = getSourceConfigurationClass(context);
//2.创建一个配置类解析器,然后递归加载并处理应用中所有的配置类
ConfigClassParser parser = new ConfigClassParser(context);
parser.parser(sourceConfigurationClass);
//3.1向IoC容器中注册@Bean方法对应的BeanDefinition
loadBeanDefinitionsFromBeanMethods(parser.configurationClasses);
//3.2向IoC容器中注册ImportBeanDefinitionRegistrar导入的BeanDefinition
loadBeanDefinitionsFromRegistrars(parser.configurationClasses);
}
递归处理的过程
1.首先处理@ComponentScan,扫描指定的package,从而会发现一系列新的配置类,然后递归处理
2.接着是处理注解@Import,导入一系列配置类后,再递归处理它们
3.最后,是解析配置类中的@Bean方法,以及之前导入的BeanDefinition注册器
public void parse (class<?>configclass) {
//1.处理(ComponentScan:根据@ComponentScan扫描指定的package,得到一系列配置类
if (hasComponentscan(configclass)) {
for (class<?> clazz : doscan(configclass))
//递归处理
this.parse(clazz);
}
//2.处理注解@Import:根据注解@Import,得到一系列被导入的配置类
if (hasImportedclasses(configclass)) {
for (cilass<?> clazz : getImports(configclass))
//递归处理
this.parse(clazz);
}
/ /3.处理@Bean方法
processBeanMethods(configclass);
//4.处理@Import导入的ImportBeanDefinitionRegistrar
processRegistrars(configclass);
//5.加入到一个全局的配置类集合中
this.configurationclasses.add(configclass);
}
四、实例化所有的单例Bean
instantiateSingletonBeans(context);
五、如果是web应用,还会启动一个web服务器,例如Tomcat
startWebServer(context);