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 的初始化、加载核心流程

 

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh(); // 准备上下文,记录容器的启动时间、标记“已启动”状态

        // Tell the subclass to refresh the internal bean factory.
        // 获取新的 BeanFactory:
        // a. 创建一个新的 BeanFactory(DefaultListableBeanFactory),设置 BeanFactory 的 id(serializationId)
        // b. 定制 beanFactory,设置 allowBeanDefinitionOverriding、allowCircularReferences(默认都是 true)
        // c. loadBeanDefinitions,scan() 扫描 BeanDefinition 并注册到 BeanFactory 中
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 初始化beanFactory:
        // a. 设置 ClassLoader、BeanPostProcessor
        // b. 注册可解析的依赖 BeanFactory、ResourceLoader、ApplicationContext、ApplicationEventPublisher,对应解析出来的值都是 AbstractApplicationContext
        // c. 注册默认的 environment beans: SystemProperties,SystemEnvironment
        prepareBeanFactory(beanFactory); // 1. 初始化 beanFactory( 设置 ClassLoader、BeanPostProcessor,注册几个特殊的 bean,例如 environment、systemProperties 等)

        try {
            // Allows post-processing of the bean factory in context subclasses. 
            // 允许对 BeanFactory 做修改,比如:
            // a. 注册特殊的 BeanPostProcessor(如:ServletContextAwareProcessor)
            // b. 注册特殊的 scopes,ResolvableDependency 或 bean
            //      注册 scopes 如:web-specific scopes ("request", "session", "globalSession", "application") 
            //      注册 ResolvableDependency 如:ServletRequest, ServletResponse, HttpSession, WebRequest(对应的都是对象工厂 ObjectFactory)
            //      注册 bean 如:web-specific environment beans ("servletContext", "servletConfig", "contextParameters", "contextAttributes")
            // c. scan() 扫描 BeanDefinition
            // 在 bean factory 初始化之后修改 bean factory。此时,bean definition 将被加载,但是 bean 还没有被初始化。此时,可以往 bean factory 中注册一些特殊的 bean definition,注册 BeanPostProcessors 等
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory); // 2. 调用BeanFactoryPostProcessor.postProcessBeanFactory。(ConfigurationClassPostProcessor 就是在这里被调用的// Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory); // 3. 注册 BeanPostProcessors

            // Initialize message source for this context.
            initMessageSource();  // 4. 初始化 MessageSource(国际化资源文件)
       // Initialize event multicaster for this context.
            initApplicationEventMulticaster(); // 5. 初始化事件广播器 EventMulticaster

            // Initialize other special beans in specific context subclasses.
            onRefresh(); // 6. 初始化一些特殊 bean。如:创建 web 容器,例如tomcat,jetty,undertow, 动态注册 servlet,filter 等

            // Check for listener beans and register them.
            registerListeners(); // 7. 添加 ApplicationListener 到事件广播器 EventMulticaster 中

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory); // 8. 初始化bean(延迟加载除外)。(最复杂最核心)

            // Last step: publish corresponding event.
            finishRefresh(); // 执行 Lifecycle#start() 方法,发布ContextRefreshedEvent事件
        }

        catch (BeansException ex) {
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();
            // Reset 'active' flag.
            cancelRefresh(ex);
            // Propagate exception to caller.
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

 

 

 

 

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

 

bean 创建的三步走:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
createBean() --> doCreateBean()

1. createBeanInstance()  // 通过反射创建 bean 的实例
2. populateBean()    // 填充 bean 里面的属性值,包括 @AutoWired、@Resource、@Value 标记的属性
3. initializeBean()    // 对 bean 进行初始化工作,包括一些初始化方法的执行,如:awareMethods、BeanPostProcessor、initMethods
// 参考方法:AbstractAutowireCapableBeanFactory#initializeBean()
// 其中,@ConfigurationProperties 标记的 bean 的属性注入,就选择了使用 BeanPostProcessor 来处理
// 具体的处理可查看 ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization()

 

数据结构:

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

 

posted on 2019-12-25 11:15  快鸟  阅读(679)  评论(0编辑  收藏  举报