• 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
  • 相关阅读:
    老毛桃装系统详解
    Eclipse常用快捷键
    oracle数据库查询日期sql语句(范例)、向已经建好的表格中添加一列属性并向该列添加数值、删除某一列的数据(一整列)
    java编程中Properties类的具体作用和使用!
    电感、磁珠和0欧电阻
    AXI总线(转)
    NOR Flash的学习
    allegro中如何添加安装孔(注:在PCB图纸中添加)
    转:一个计算机专业毕业的银行员工工作感受
    Allegro中常见的文件格式
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/12095640.html
Copyright © 2020-2023  润新知