从SpringApplication开始

一般情况下启动SpringBoot都是新建一个类包含main方法,然后使用SpringApplication.run来启动程序:

@SpringBootApplication public class AutoConfigApplication {      public static void main(String[] args){         ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(AutoConfigApplication.class,args);     } } 

SpringApplication.run接收两个参数分别为:primarySource、运行参数(args),上面的代码使用AutoConfigApplication.class作为primarySource。SpringApplication还有一个实例方法也叫run,SpringBoot的大部分启动都由实例run方法来完成的,其中构造ApplicationContext由createApplicationContext方法完成:

protected ConfigurableApplicationContext createApplicationContext() {         Class<?> contextClass = this.applicationContextClass;         if (contextClass == null) {             try {                 switch (this.webApplicationType) {                 case SERVLET:                     contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);                     break;                 case REACTIVE:                     contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);                     break;                 default:                     contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);                 }             }             catch (ClassNotFoundException ex) {                 throw new IllegalStateException(                         "Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);             }         }         return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);     }

createApplicationContext根据this.webApplicationType来构造ApplicationContext,不同的环境都会使用不同的实例,但本文非web环境所有构造的时候会使用AnnotationConfigApplicationContext类。创建AnnotationConfigApplicationContext的时候会调用默认构造方法

public AnnotationConfigApplicationContext() {     this.reader = new AnnotatedBeanDefinitionReader(this);     this.scanner = new ClassPathBeanDefinitionScanner(this); }

AnnotationConfigApplicationContext默认构造函数创建两个对象:

  • reader(AnnotatedBeanDefinitionReader):用于手动注册bean
  • scanner(ClassPathBeanDefinitionScanner): 用于扫描Component、Repository、Service等注解

AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner会注册一些注解处理器,注册的方式都是使用AnnotationConfigUtils的registerAnnotationConfigProcessors方法