SpringBoot 启动流程

(Version: 2.1.0.RELEASE)

1. 启动入口

@SpringBootApplication
public class KvnMainApplication {
    public static void main(String[] args) {
        // 1. 创建和初始化 SpringApplication 对象
        SpringApplication app = new SpringApplication(KvnMainApplication.class);
        // 2. 启动 SpringBoot 程序
        app.run(args);
    }
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath(); // 1. 识别应用类型:NONE、SERVLET 或者 REACTIVE
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 2. 从 spring.factories 文件中加载 ApplicationContextInitializer 初始器,并赋值给 initializers
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); // 3. 从 spring.factories 文件中加载 ApplicationListener 监听器,并赋值给 listeners
    this.mainApplicationClass = deduceMainApplicationClass(); // 4. 保存 SpringBoot 程序启动类(这里为:KvnMainApplication.class)
}

SpringBoot SPI:

1. org.springframework.boot.SpringApplication.getSpringFactoriesInstances(Class<T> type)
    1.1 org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(type, classLoader)
        1.1.1 org.springframework.core.io.support.SpringFactoriesLoader.loadSpringFactories(ClassLoader classLoader) // 加载 classpath 下所有的 META-INF/spring.factories 文件,并把结果缓存在 cache 中
    1.2 org.springframework.boot.SpringApplication.createSpringFactoriesInstance // 实例化 type 对应的所有 SPI 扩展类对象
    1.3 AnnotationAwareOrderComparator.sort(instances) // 对实例化出的所有对象进行排序

SpringBoot SPI 在获取 type 对应的 SPI 扩展对象集合时,是使用的扩展类的构造器反射生成的实例。
SpringBoot 支持两种模式来获取 SPI 扩展对象集合:
1. 使用无参构造函数
  例:
  org.springframework.boot.SpringApplication.getSpringFactoriesInstances(ApplicationContextInitializer.class)
2. 使用有参构造函数
  例:
  Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
  getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args);

2. 启动主流程

2.1 主要步骤

/**
* 启动 SpringBoot 应用程序,创建一个新的 ApplicationContext,并且刷新应用上下文 ApplicationContext
*/    
public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args); // 1. 获取 SpringApplicationRunListener 监听器
    listeners.starting(); // 2. 执行所有 listener 的 starting 方法
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 3. 准备环境
        configureIgnoreBeanInfo(environment);
        Banner printedBanner = printBanner(environment); // 打印 banner 信息
        context = createApplicationContext(); // 创建一个新的上下文
        exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context);
        prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 4. 准备上下文
        refreshContext(context); // 5. 刷新上下文
        afterRefresh(context, applicationArguments); // 刷新上下文之后的扩展点,默认是空实现
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        listeners.started(context); // 6. 执行所有 SpringApplicationRunListener 的 started 方法
        callRunners(context, applicationArguments); // 7. 执行所有的 ApplicationRunner、CommandLineRunner 的 run 方法
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, listeners);
        throw new IllegalStateException(ex);
    }

    try {
        listeners.running(context); // 8. 执行所有 SpringApplicationRunListener 的 running 方法
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, null);
        throw new IllegalStateException(ex);
    }
    return context;
}

2.2 关键步骤拆解

1. org.springframework.boot.SpringApplication.getRunListeners
    1.1 getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args)  // 获取 spring.factories 文件中配置的 SpringApplicationRunListener SPI 实例
    // 这里 SpringBoot 会加载一个 EventPublishingRunListener ,用于发布 SpringApplicationEvent 事件
     
    
2. org.springframework.boot.SpringApplicationRunListeners.starting() // 执行所有的 SpringApplicationRunListener 的 starting()。这里只有 EventPublishingRunListener
    2.1 org.springframework.boot.context.event.EventPublishingRunListener.starting()
        2.1.1 org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(ApplicationEvent event) // 广播 ApplicationStartingEvent 事件
        // initialMulticaster 将事件广播给所有对此事件感兴趣的 listener。这些 listener 就是在 new SpringApplication() 时设置的 ApplicationListener 集合
        // listeners:
        0 = {ConfigFileApplicationListener@1664} 
        1 = {AnsiOutputApplicationListener@1665} 
        2 = {LoggingApplicationListener@1666} 
        3 = {ClasspathLoggingApplicationListener@1667} 
        4 = {BackgroundPreinitializer@1668} 
        5 = {DelegatingApplicationListener@1669} 
        6 = {ParentContextCloserApplicationListener@1670} 
        7 = {ClearCachesApplicationListener@1671} 
        8 = {FileEncodingApplicationListener@1672} 
        9 = {LiquibaseServiceLocatorApplicationListener@1673}
        


每一种应用上下文 ApplicationContext 对应的类 :
    DEFAULT : org.springframework.context.annotation.AnnotationConfigApplicationContext
    SERVLET : org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
    REACTIVE : org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext
        
3. org.springframework.boot.SpringApplication.prepareEnvironment
    3.1 org.springframework.boot.SpringApplication.getOrCreateEnvironment() // 创建一个 ConfigurableEnvironment。此例子为:new StandardServletEnvironment()
        3.1.1 org.springframework.core.env.AbstractEnvironment.AbstractEnvironment()  // 调用父类 AbstractEnvironment 的构造函数,创建一个 MutablePropertySources
            3.1.1.1 org.springframework.core.env.AbstractEnvironment.customizePropertySources // 子类扩展点
                3.1.1.1.1 org.springframework.web.context.support.StandardServletEnvironment.customizePropertySources // 添加 servletConfigInitParams、servletContextInitParams 到 MutablePropertySources
                3.1.1.1.2 org.springframework.core.env.StandardEnvironment.customizePropertySource // 添加 systemProperties、systemEnvironment 到 MutablePropertySources
    3.2 org.springframework.boot.SpringApplication.configureEnvironment // 配置 ConfigurableEnvironment
        3.2.1 org.springframework.core.env.ConfigurablePropertyResolver.setConversionService // 添加 ConversionService(属性转换器 service),初始化默认的属性转换器 converters
        3.2.2 org.springframework.boot.SpringApplication.configurePropertySources // 如果启动命令中有参数:添加 commandLineArgs 到 MutablePropertySources
        3.2.3 org.springframework.boot.SpringApplication.configureProfiles
            3.2.3.1 org.springframework.core.env.ConfigurableEnvironment.setActiveProfiles // 设置 environment 激活的 profiles
    3.3 org.springframework.boot.SpringApplicationRunListeners.environmentPrepared
        3.3.1 org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared // 广播 ApplicationEnvironmentPreparedEvent 事件
            3.3.1.1 org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEvent // 接收 ApplicationEnvironmentPreparedEvent 事件
                3.3.1.1.1 org.springframework.boot.env.RandomValuePropertySource.addToEnvironment // 添加 RANDOM_PROPERTY_SOURCE 到 MutablePropertySources
                3.3.1.1.2 org.springframework.boot.context.config.ConfigFileApplicationListener.Loader.load() // 加载 application.yml(or .properties),添加到 MutablePropertySources。这里会激活配置文件中的 profiles
            
    3.4 org.springframework.boot.SpringApplication.bindToSpringApplication // 将 environment Bind 到 SpringApplication 实例上,使它的属性支持外部化配置
    3.5 org.springframework.boot.context.properties.source.ConfigurationPropertySources.attach // 将 environment 中的 propertySources 包装成 configurationProperties 添加到 environment 中,使它支持 PropertySourcesPropertyResolver 调用。 name=configurationProperties 的 PropertySources 优先级最高

4. org.springframework.boot.SpringApplication.prepareContext
    4.1 org.springframework.boot.SpringApplication.applyInitializers // 初始化上下文。执行 ApplicationContextInitializer.initialize(context) 
    4.2 org.springframework.boot.SpringApplicationRunListeners.contextPrepared // 上下文准备完毕。广播 ApplicationContextInitializedEvent 事件
    4.3 org.springframework.boot.SpringApplication.load // 加载 bean 到 ApplicationContext 中。此处只会加载 KvnMainApplication
    4.4 org.springframework.boot.SpringApplicationRunListeners.contextLoaded // 上下文加载完毕。广播 ApplicationPreparedEvent 事件


5. org.springframework.boot.SpringApplication.refreshContext
    5.1 org.springframework.context.support.AbstractApplicationContext.refresh() // bean 的初始化,加载,代理等。最核心的部分
    5.2 org.springframework.context.support.AbstractApplicationContext.registerShutdownHook // 注册jvm钩子,优雅停机的关键点

6. org.springframework.boot.SpringApplicationRunListeners.started // 应用启动完毕。广播 ApplicationStartedEvent 事件

7. org.springframework.boot.SpringApplication.callRunners    // 执行 ApplicationRunner、CommandLineRunner run方法

8. org.springframework.boot.SpringApplicationRunListeners.running // 广播 ApplicationReadyEvent 事件

================================
SpringBoot relaxBinding :
org.springframework.boot.SpringApplication.bindToSpringApplication(ConfigurableEnvironment environment)
Binder.get(environment).bind("spring.main", Bindable.ofInstance(this));
// 所以可以通过 spring.main.banner-mode=off 来关闭 banner

servletConfigInitParams、servletContextInitParams 最初是作为 StubPropertySource 添加到 MutablePropertySources 中的。StubPropertySource 是 PropertySource 存根,里面并没有值,等到 servlet 容器启动时才会有值。


加载 application.properties 的优先级:
0 = "file:./config/"
1 = "file:./"
2 = "classpath:/config/"
3 = "classpath:/"


Environment:
与属性相关的 Environment 对象的作用是为用户提供一个方便的服务接口,用于配置属性源并从中解析属性。

数据结构:

 1 // SpringBoot 配置类模型:
 2 final class ConfigurationClass {
 3     private final AnnotationMetadata metadata;
 4     private final Resource resource;
 5     private String beanName;
 6     private final Set<ConfigurationClass> importedBy = new LinkedHashSet<>(1);
 7     private final Set<BeanMethod> beanMethods = new LinkedHashSet<>();
 8     private final Map<String, Class<? extends BeanDefinitionReader>> importedResources =new LinkedHashMap<>();
 9     private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =new LinkedHashMap<>();
10     final Set<String> skippedBeanMethods = new HashSet<>();
11     ...
12 }

3、 Bean 的初始化、加载核心流程

 1 public void refresh() throws BeansException, IllegalStateException {
 2     synchronized (this.startupShutdownMonitor) {
 3         // Prepare this context for refreshing.
 4         prepareRefresh();
 5 
 6         // Tell the subclass to refresh the internal bean factory.
 7         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 8 
 9         // Prepare the bean factory for use in this context.
10         prepareBeanFactory(beanFactory); // 1. 初始化 beanFactory( 设置 ClassLoader、BeanPostProcessor,注册几个特殊的 bean,例如 environment、systemProperties 等)
11 
12         try {
13             // Allows post-processing of the bean factory in context subclasses. 
// 在 bean factory 初始化之后修改 bean factory。此时,bean definition 将被加载,但是 bean 还没有被初始化。此时,可以往 bean factory 中注册一些特殊的 bean definition,注册 BeanPostProcessors 等
14 postProcessBeanFactory(beanFactory); 15 16 // Invoke factory processors registered as beans in the context. 17 invokeBeanFactoryPostProcessors(beanFactory); // 2. 调用 BeanFactoryPostProcessor 18 19 // Register bean processors that intercept bean creation. 20 registerBeanPostProcessors(beanFactory); // 3. 注册 BeanPostProcessors 21 22 // Initialize message source for this context. 23 initMessageSource(); // 4. 初始化 MessageSource(国际化资源文件) 24 25 // Initialize event multicaster for this context. 26 initApplicationEventMulticaster(); // 5. 初始化事件广播器 EventMulticaster 27 28 // Initialize other special beans in specific context subclasses. 29 onRefresh(); // 6. 初始化一些特殊 bean。如:创建容器,例如tomcat,jetty,undertow, 动态添加servlet,filter等 30 31 // Check for listener beans and register them. 32 registerListeners(); // 7. 添加 ApplicationListener 到事件广播器 EventMulticaster 中 33 34 // Instantiate all remaining (non-lazy-init) singletons. 35 finishBeanFactoryInitialization(beanFactory); // 8. 初始化bean(延迟加载除外)。(最复杂最核心) 36 37 // Last step: publish corresponding event. 38 finishRefresh(); 39 } 40 41 catch (BeansException ex) { 42 if (logger.isWarnEnabled()) { 43 logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); 44 } 45 46 // Destroy already created singletons to avoid dangling resources. 47 destroyBeans(); 48 49 // Reset 'active' flag. 50 cancelRefresh(ex); 51 52 // Propagate exception to caller. 53 throw ex; 54 } 55 56 finally { 57 // Reset common introspection caches in Spring's core, since we 58 // might not ever need metadata for singleton beans anymore... 59 resetCommonCaches(); 60 } 61 } 62 }
2. org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors
    2.1 org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors // 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。执行顺序为:PriorityOrdered --> Ordered --> the rest(no ordered)
        2.1.1 org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry // 处理 @Configuration 标记的类:加载 @Bean 定义、加载 @Import 中的 Bean 定义。因为在 @Configuration 类中声明的任何 Bean 方法都必须在其他任何 BeanFactoryPostProcessor 执行之前注册它们相应的 Bean 定义
            2.1.1.1 org.springframework.context.annotation.ConditionEvaluator.shouldSkip // 处理 @Condition 条件,判断是否需要加载这个 @Configuration 配置类
            2.1.1.2 org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass    // 解析 @Configuration 类中声明的 Bean,包括: @Component、@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean
                2.1.1.2.1 org.springframework.context.annotation.ComponentScanAnnotationParser.parse // 处理 @ComponentScan。由于 @SpringBootApplication 继承了 @ComponentScan 注解,所以它会默认自动扫描 SpringBoot 启动类所在包下面的 Bean
            2.1.1.3 org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions // 加载所有声明的 Bean 到 Spring 容器 BeanDefinitionRegistry(还会判断一遍 shouldSkip())
                
    2.2 org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors // 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory。执行顺序为:PriorityOrdered --> Ordered --> the rest(no ordered)
        2.2.1 org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory // 通过 cglib 增强 @Configuration 配置类,通过增强来处理 @Bean 方法上的 bean 参数自动注入(ConfigurationClassEnhancer#CALLBACKS)。(重要)
            2.2.1.1 org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses // cglib 增强 @Configuration 配置类
    2.3 org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors // 执行 BeanFactoryPostProcessor.postProcessBeanFactory。执行顺序为:PriorityOrdered --> Ordered --> the rest(no ordered)
        2.3.1 org.springframework.context.support.PropertySourcesPlaceholderConfigurer.postProcessBeanFactory // 处理 Bean 中的占位符 @Value

注:    
2.1.1.2 所有解析出来的 Bean 分为三种:
I. 扫描出来的 @Component Bean
    Spring 会为这类 Bean new 一个 ConfigurationClass,并最终添加到 ConfigurationClassParser#configurationClasses 变量中
II. @Bean 定义的 Bean
    Spring 会将这类 Bean 添加到相应的 ConfigurationClass#beanMethods 变量中
III. 使用 @ImportResource 定义在 *.xml 中的 Bean
    Spring 会将这类 Bean 添加到相应的 ConfigurationClass#importedResources 变量中

最终,这些声明的 Bean 会在 org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions 方法中加载 Bean
    
  1 org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
  2 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
  3     List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
  4     String[] candidateNames = registry.getBeanDefinitionNames();
  5 
  6     for (String beanName : candidateNames) {
  7         BeanDefinition beanDef = registry.getBeanDefinition(beanName);
  8         if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
  9                 ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
 10             if (logger.isDebugEnabled()) {
 11                 logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
 12             }
 13         }
 14         else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
 15             configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
 16         }
 17     }
 18 
 19     // Return immediately if no @Configuration classes were found
 20     if (configCandidates.isEmpty()) {
 21         return;
 22     }
 23 
 24     // Sort by previously determined @Order value, if applicable
 25     // 对 @Configuration 标记的类进行排序(支持 @Value 注解)
 26     configCandidates.sort((bd1, bd2) -> {
 27         int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
 28         int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
 29         return Integer.compare(i1, i2);
 30     });
 31 
 32     // Detect any custom bean name generation strategy supplied through the enclosing application context
 33     SingletonBeanRegistry sbr = null;
 34     if (registry instanceof SingletonBeanRegistry) {
 35         sbr = (SingletonBeanRegistry) registry;
 36         if (!this.localBeanNameGeneratorSet) {
 37             BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
 38             if (generator != null) {
 39                 this.componentScanBeanNameGenerator = generator;
 40                 this.importBeanNameGenerator = generator;
 41             }
 42         }
 43     }
 44 
 45     if (this.environment == null) {
 46         this.environment = new StandardEnvironment();
 47     }
 48 
 49     // Parse each @Configuration class
 50     ConfigurationClassParser parser = new ConfigurationClassParser(
 51             this.metadataReaderFactory, this.problemReporter, this.environment,
 52             this.resourceLoader, this.componentScanBeanNameGenerator, registry);
 53 
 54     Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
 55     Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
 56     do {
 57         parser.parse(candidates); // 解析 @Configuration 中的 bean,包括:@Component、@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean。最核心的部分
 58         parser.validate();
 59 
 60         Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
 61         configClasses.removeAll(alreadyParsed);
 62 
 63         // Read the model and create bean definitions based on its content
 64         if (this.reader == null) {
 65             this.reader = new ConfigurationClassBeanDefinitionReader(
 66                     registry, this.sourceExtractor, this.resourceLoader, this.environment,
 67                     this.importBeanNameGenerator, parser.getImportRegistry());
 68         }
 69         this.reader.loadBeanDefinitions(configClasses); // 加载 @Configuration 类中定义的 Bean
 70         alreadyParsed.addAll(configClasses);
 71 
 72         candidates.clear();
 73         if (registry.getBeanDefinitionCount() > candidateNames.length) {
 74             String[] newCandidateNames = registry.getBeanDefinitionNames();
 75             Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
 76             Set<String> alreadyParsedClasses = new HashSet<>();
 77             for (ConfigurationClass configurationClass : alreadyParsed) {
 78                 alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
 79             }
 80             for (String candidateName : newCandidateNames) {
 81                 if (!oldCandidateNames.contains(candidateName)) {
 82                     BeanDefinition bd = registry.getBeanDefinition(candidateName);
 83                     if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
 84                             !alreadyParsedClasses.contains(bd.getBeanClassName())) {
 85                         candidates.add(new BeanDefinitionHolder(bd, candidateName));
 86                     }
 87                 }
 88             }
 89             candidateNames = newCandidateNames;
 90         }
 91     }
 92     while (!candidates.isEmpty());
 93 
 94     // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
 95     if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
 96         sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());  // 处理 @Import 注入的 Bean 定义
 97     }
 98 
 99     if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
100         // Clear cache in externally provided MetadataReaderFactory; this is a no-op
101         // for a shared cache since it'll be cleared by the ApplicationContext.
102         ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
103     }
104 }
View Code


3. org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors // 注册 BeanPostProcessors
    3.1 org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors // 注册顺序为: PriorityOrdered --> Ordered --> the rest(no ordered)

    
6. org.springframework.context.support.AbstractApplicationContext.onRefresh
    6.1 org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer // 创建 web 容器
    6.2 org.springframework.web.context.support.GenericWebApplicationContext.initPropertySources // 初始化 servlet 相关的 PropertySources

    
8. org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization
    8.1 DefaultListableBeanFactory.preInstantiateSingletons --> AbstractBeanFactory.doGetBean --> DefaultSingletonBeanRegistry.getSingleton (解决循环依赖) --> AbstractAutowireCapableBeanFactory.createBean
    8.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean // bean 的核心创建流程
        8.2.1 applyMergedBeanDefinitionPostProcessors() // 允许 post-processors 修改 bean definition
        8.2.2 populateBean()  // 填充 bean 属性
        8.2.3 initializeBean() // 初始化 bean

创建 bean 的过程:

1. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean // 创建 bean 的核心方法:创建一个bean实例,填充bean实例,执行 post-processors 等
    1.1 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation // 让 BeanPostProcessors 有机会来创建一个代理 bean。Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        1.1.1 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation // 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
        1.1.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization // 执行 BeanPostProcessor.postProcessAfterInitialization
    1.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
        1.2.1 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors // 执行 MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition。允许 post-processors 修改 bean definition。比如:解析 bean 的依赖关系(@Value、@Autowired、@Resource等)存放到 bean definition中
        1.2.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean // 填充 bean 的属性
            1.2.2.1 org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
            1.2.2.2 org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor.postProcessProperties // 处理属性注入:@Value, @Autowired, @Resource 等
        1.2.3 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean // 初始化 bean 
            1.2.3.1 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods // 执行 aware 方法:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
            1.2.3.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization // 执行 BeanPostProcessor.postProcessBeforeInitialization
            1.2.3.3 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods
                1.2.3.3.1 org.springframework.beans.factory.InitializingBean.afterPropertiesSet // 执行 afterPropertiesSet() 方法
                1.2.3.3.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod // 执行自定义的 init 方法
            1.2.3.4 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization // 执行 BeanPostProcessor.postProcessAfterInitialization

数据结构:

BeanDefinition

RootBeanDefinition

 1 public class RootBeanDefinition extends AbstractBeanDefinition {
 2 
 3     private BeanDefinitionHolder decoratedDefinition;
 4 
 5     private AnnotatedElement qualifiedElement;
 6 
 7     /** Determines if the definition needs to be re-merged. */
 8     volatile boolean stale;
 9 
10     boolean allowCaching = true;
11 
12     boolean isFactoryMethodUnique = false;
13 
14     volatile ResolvableType targetType;
15 
16     /** Package-visible field for caching the determined Class of a given bean definition. */
17     volatile Class<?> resolvedTargetType;
18 
19     /** Package-visible field for caching if the bean is a factory bean. */
20     volatile Boolean isFactoryBean;
21 
22     /** Package-visible field for caching the return type of a generically typed factory method. */
23     volatile ResolvableType factoryMethodReturnType;
24 
25     /** Package-visible field for caching a unique factory method candidate for introspection. */
26     volatile Method factoryMethodToIntrospect;
27 
28     /** Common lock for the four constructor fields below. */
29     final Object constructorArgumentLock = new Object();
30 
31     /** Package-visible field for caching the resolved constructor or factory method. */
32     Executable resolvedConstructorOrFactoryMethod;
33 
34     /** Package-visible field that marks the constructor arguments as resolved. */
35     boolean constructorArgumentsResolved = false;
36 
37     /** Package-visible field for caching fully resolved constructor arguments. */
38     Object[] resolvedConstructorArguments;
39 
40     /** Package-visible field for caching partly prepared constructor arguments. */
41     Object[] preparedConstructorArguments;
42 
43     /** Common lock for the two post-processing fields below. */
44     final Object postProcessingLock = new Object();
45 
46     /** Package-visible field that indicates MergedBeanDefinitionPostProcessor having been applied. */
47     boolean postProcessed = false;
48 
49     /** Package-visible field that indicates a before-instantiation post-processor having kicked in. */
50     volatile Boolean beforeInstantiationResolved;
51 
52     // 存放 @Value、@Autowired、@Resource、@Inject、@EJB、@WebServiceRef 等标记的注入属性
53     private Set<Member> externallyManagedConfigMembers;
54 
55     // 存放 @PostConstruct 标记的方法
56     private Set<String> externallyManagedInitMethods;
57 
58     // 存放 @PreDestroy 标记的方法
59     private Set<String> externallyManagedDestroyMethods;
60     
61     ......
62 }
View Code
原文地址:https://www.cnblogs.com/kevin-yuan/p/12095640.html