springboot 自动装配原理概述:

      1.当启动Springboot应用程序时,会先创建 SpringApplication 对象。在对象的构造函数中会进行参数的初始化工作,最主要的是判断当前应用程序的类型以及读取初始化器和监听器。在这个过程中会加载整           个应用程序中的spring.factories文件,将文件的内容放到缓存对象中,方便后续获取。

      2. SpringApplication创建完成后,开始执行run方法,进行整个应该程序的启动。在启动过程中,最主要的有两个方法,prepareContext,refreshContext方法。程序会在这两个方法中完成自动装配的核心功                能。具体包括 上下文对象创建,banner打印,异常报告器的准备等逻辑处理,为后续程序完整启动做准备。

      3. 在 prepareContext 方法中,主要完成对上下对象的初始化操作,具体包括属性值的设置。其中有一个非常重要的方法load。load 主要将当前启动类作为一个bean,以beanDefinition的配置注册到                          beanFactory 中,为后续调用 BeanFactoryPostProcessor的增强方法做准备。 后续 执行时,发现程序中有@Configuration配置时,会触发@SrpingBootApplication,@EnableAutoConfiguration 等注解的解析工作。

      4. 在 refreshContext 方法中,会进行整个容器的刷新过程。这个方法会间接调用spring中refresh方法,完成整个Spring应用程序的启动。其中在依次调用 BeanFactoryPostProcessor 实现类的方法时,会使             用到一个主要的实现类 ConfigurationClassPostProcessor 处理类。在调用该类 postProcessBeanDefinitonRegister 方法,紧接着调用 postProcessBeanFactory方法时会进行解析配置相关的注解。主要包             括 @PropertySource, @ComponentScan, @Bean,@Import 等注解,其中最重要的时@Import注解。

      5. 在解析@Import注解时,会调用一个 getImports 方法,从主要类开始递归解析注解,找到所有@Import注解信息,然后再调用 processImport方法对Import类进行分类处理,此处主要识别                                        AutoConfigurationImportSelect 归属的ImportSelect 子类,后续过程会调用 deferredImportSelectorHandler 中的process 方法,来加载所有的 EnableAutoConfiguration 的配置。

 

一.  SpringApplication 创建:

        org.springframework.boot.SpringApplication(Class<?>... primarySources)

            org.springframework.boot.SpringApplication#SpringApplication(ResourceLoader, Class<?>...)

        1. 设置资源引导(ResourceLoader)。

        2. 设置主要资源信息(primarySources)。

        3. 推断Web应用类型(webApplicationType)。默认有三种:java标准的 SERVLET 类型, 反应式 REACTIVE 类型,以及未知的 NONE 类型。

        4. 设置初始化程序(ApplicationContextInitializer)对象实例列表 (List<ApplicationContextInitializer<?>>)。即读取 jar 文件中 META-INF/spring.factories 配置的所有 org.springframework.context.ApplicationContextInitializer 实现。

         常用的实现类:

org.springframework.boot.devtools.restart.RestartScopeInitializer 
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
org.springframework.boot.context.ContextIdApplicationContextInitializer
org.springframework.boot.context.config.DelegatingApplicationContextInitializer
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

       5. 设置监听器(ApplicationListener)对象实例列表 (List<ApplicationListener<?>>)。即 jar 文件中 META-INF/spring.factories 配置的所有 org.springframework.context.ApplicationListener 实现。

        常用的实现类:

org.springframework.boot.devtools.restart.RestartApplicationListener
org.springframework.boot.devtools.logger.DevToolsLogFactory.Listener
org.springframework.boot.autoconfigure.BackgroundPreinitializer
org.springframework.boot.ClearCachesApplicationListener
org.springframework.boot.builder.ParentContextCloserApplicationListener
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
org.springframework.boot.context.FileEncodingApplicationListener
org.springframework.boot.context.config.AnsiOutputApplicationListener
org.springframework.boot.context.config.ConfigFileApplicationListener
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener
org.springframework.boot.context.logging.LoggingApplicationListener
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

  6. 推断运行程序的主类类型(mainApplicationClass)。

    /**
     * Create a new {@link SpringApplication} instance. The application context will load
     * beans from the specified primary sources (see {@link SpringApplication class-level}
     * documentation for details. The instance can be customized before calling
     * {@link #run(String...)}.
     * @param resourceLoader the resource loader to use
     * @param primarySources the primary bean sources
     * @see #run(Class, String[])
     * @see #setSources(Set)
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    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();
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
    }
View Code

 

二. Springboot 的SPI机制加载类逻辑

      org.springframework.boot.SpringApplication#getSpringFactoriesInstances(Class<T> type)
             org.springframework.boot.SpringApplication#getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args)
                  org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames(Class<?> factoryType, ClassLoader classLoader)
                  org.springframework.boot.SpringApplication#createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
ClassLoader classLoader, Object[] args, Set<String> names)

       1. 获得当前环境的类加载器。默认是从 Thread.currentThread().getContextClassLoader() 获取的。

                JDK8中为           :sun.misc.Launcher$AppClassLoader。

                JDK9及以后版本:jdk.internal.loader.ClassLoaders$AppClassLoader

       2. 从 META-INF/spring.factories 配置中寻找 type 实现类的配置列表。如果已加载,则从本地缓存中读取。

       3. 根据传递的参数,实例化 type 的实例。

       4. 排序 type 实现类列表,并返回。

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = getClassLoader();
        // Use names and ensure unique to protect against duplicates
        Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

 

三. SpringApplication#run() 分析

       org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)

           org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])

                  org.springframework.boot.SpringApplication#run(java.lang.String...)

      (一) run 方法概述:

      1. 创建 StopWatch 实例,记录当前开始时间,以及任务名称等信息。

      2. 设置系统属性 java.awt.headless 值。默认为true。Headless是指服务器的无显示设备状态。

      3.  获取程序运行监听器辅助类(SpringApplicationRunListeners)实例,并触发 starting() 事件。SpringApplicationRunListeners#starting()

            SpringApplicationRunListener 监听 SpringApplication 类执行run方法触发的七个事件。这七个事件对应运行时的七个周期节点,开发人员根据需要,可以在相关节点进行扩展。

            该接口默认只有一个实现 EventPublishingRunListener 类。创建时注入了 SpringApplication 类,事件广播类 SimpleApplicationEventMulticaster 实例。最终将SpringApplication 事件监听器和Spring的事件监听器关联上。

      4.  创建 请求参数包装类实例。

      5. 预处理环境变量信息。SpringApplication#prepareEnvironment()

      6.  设置是否忽略 beanInfo 信息参数。 spring.beaninfo.ignore

      7.  打印 Banner 信息。SpringApplication#printBanner() 。创建对象 SpringApplicationBannerPrinter 实例,打印Banner。

      8.  根据Web应用类型(webApplicationType) 创建程序上下文实例(ConfigurableApplicationContext)。

                 SERVLET      AnnotationConfigServletWebServerApplicationContext

                REACTIVE     AnnotationConfigReactiveWebServerApplicationContext

               默认类型          AnnotationConfigApplicationContext

               当前环境创建   AnnotationConfigServletWebServerApplicationContext 实例,进行spring 逻辑的处理。

      9.  获得 异常报告处理接口(SpringBootExceptionReporter)的所有实现,并创建实例。默认实现类: org.springframework.boot.diagnostics.FailureAnalyzers

      10. 预处理 程序上下文。SpringApplication#prepareContext()

      11. 刷新 程序上下文。注册程序停机Hook,并调用Spring 的 AbstractApplicationContext#refresh() 方法,进行Spring 的程序运行环境的创建。

      12. 刷新 程序上下文后置处理。留给用户扩展的方法。

      13. 调用 StopWatch 实例stop() 方法,标记任务执行完成,记录任务结束时间。

      14. 执行 started() 方法。SpringApplicationRunListeners#started()

      15. 找到注入的所有 ApplicationRunner,CommandLineRunner 实现类,依次调用。默认没用实现类。

      16. 执行 runing() 方法。SpringApplicationRunListeners#running(ConfigurableApplicationContext context)。

      17. 如果出现异常,进行异常处理。

     SpringApplication#handleRunFailure(ConfigurableApplicationContext context, Throwable exception, Collection<SpringBootExceptionReporter> exceptionReporters, SpringApplicationRunListeners listeners)

   (二) 重要步骤详解

     SpringApplicationRunListeners#starting() 事件详解:

           org.springframework.boot.SpringApplicationRunListeners#starting()
                  org.springframework.boot.context.event.EventPublishingRunListener#starting()
                      this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));

                      org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(org.springframework.context.ApplicationEvent)

     常见支持 ApplicationStartingEvent 事件的监听器有如下几个:  

             org.springframework.boot.devtools.restart.RestartApplicationListener,
             org.springframework.boot.context.logging.LoggingApplicationListener,
             org.springframework.boot.autoconfigure.BackgroundPreinitializer,
             org.springframework.boot.context.config.DelegatingApplicationListener,
             org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

RestartApplicationListener 监听器, 程序调试时使用的,方便自动重启服务。经过相关逻辑处理后,设置使用 org.springframework.boot.devtools.restart.RestartLauncher 类实现服务的重新启动。

org.springframework.boot.devtools.restart.RestartApplicationListener#onApplicationEvent(ApplicationEvent event)
      org.springframework.boot.devtools.restart.RestartApplicationListener#onApplicationStartingEvent(ApplicationStartingEvent event)
            org.springframework.boot.devtools.restart.Restarter#initialize(java.lang.String[], boolean, org.springframework.boot.devtools.restart.RestartInitializer, boolean)
                  org.springframework.boot.devtools.restart.Restarter#initialize(boolean)
                         org.springframework.boot.devtools.restart.Restarter#immediateRestart

 

LoggingApplicationListener  监听器,进行日志的初始化处理。当前环境配置的是Logback日志实现。

     org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationEvent(ApplicationEvent event)
         org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationStartingEvent(ApplicationStartingEvent event)
              org.springframework.boot.logging.logback.LogbackLoggingSystem#beforeInitialize()

 

BackgroundPreinitializer 监听器,后台线程早期初始化处理器。 当前事件不触发逻辑处理。

DelegatingApplicationListener 监听器,  和 EventPublishingRunListener 类功能类似。当前事件不触发逻辑处理。

LiquibaseServiceLocatorApplicationListener 监听器, 当前事件不触发。LiquiBase是一个用于数据库重构和迁移的开源工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。

 

        环境变量预处理 SpringApplication#prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments)

        1. 创建环境变量(ConfigurableEnvironment)的实现类。          

                        SERVLET           StandardServletEnvironment
                        REACTIVE         StandardReactiveWebEnvironment
                        default                StandardEnvironment

        2.  用 程序启动参数 和 默认环境变量配置处理。

        3.  进行环境属性 configurationProperties 处理。ConfigurationPropertySources.attach(environment)。

        4.  执行SpringApplicationRunListeners#environmentPrepared(ConfigurableEnvironment environment)方法,触发 ApplicationEnvironmentPreparedEvent 事件。

             满足 ApplicationEnvironmentPreparedEvent  事件的监听器:      

                org.springframework.boot.devtools.restart.RestartApplicationListener, 未触发相关逻辑处理。
                org.springframework.boot.context.config.ConfigFileApplicationListener, 配置处理逻辑

                          读取 EnvironmentPostProcessor 接口实现列表,依次处理属性配置:

                                  org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,
                                  org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,
                                  org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
                                  org.springframework.boot.context.config.ConfigFileApplicationListener,
                                  org.springframework.boot.devtools.env.DevToolsHomePropertiesPostProcessor,
                                  org.springframework.boot.devtools.env.DevToolsPropertyDefaultsPostProcessor,
                                  org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor

                org.springframework.boot.context.config.AnsiOutputApplicationListener,
                org.springframework.boot.context.logging.LoggingApplicationListener,  日志处理初始化
                org.springframework.boot.autoconfigure.BackgroundPreinitializer,  后台线程早期初始化处理。
                org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,  打印ClassPath路径。
                org.springframework.boot.context.config.DelegatingApplicationListener, 委派处理。此处无满足条件,无处理逻辑。
                org.springframework.boot.context.FileEncodingApplicationListener   文件字符配置检查  spring.mandatory-file-encoding

        5.  将环境变量信息绑定到应用程序上。 Binder.get(environment).bind("spring.main", Bindable.ofInstance(this));

        6.  重新进行环境属性 configurationProperties 处理。ConfigurationPropertySources.attach(environment)。

 

      根据Web应用类型(webApplicationType) 创建程序上下文实例(ConfigurableApplicationContext)

         AnnotationConfigServletWebServerApplicationContext 实例化分析:

             1. 创建BeanFactory 默认实现类 DefaultListableBeanFactory 实例。

             2.  创建  AnnotatedBeanDefinitionReader 实例,添加 BeanDefinition 配置处理器。

                   org.springframework.context.annotation.AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)
                        org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
                             org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
                                  org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry)
                                       org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry, Object)

                    ① 如果 BeanFactory 中没用配置 org.springframework.context.annotation.internalConfigurationAnnotationProcessor 名称的bean,则使用默认的 ConfigurationClassPostProcessor。

                    ② 如果 BeanFactory 中没用配置 org.springframework.context.annotation.internalAutowiredAnnotationProcessor 名称的bean,则使用默认的 AutowiredAnnotationBeanPostProcessor。

                    ② 如果 BeanFactory 中没用配置 org.springframework.context.annotation.internalCommonAnnotationProcessor 名称的bean,则使用默认的 CommonAnnotationBeanPostProcessor。

                    ② 如果 BeanFactory 中配置JPA实现,但没用配置 org.springframework.context.annotation.internalPersistenceAnnotationProcessor 名称的bean,则使用默认的 PersistenceAnnotationBeanPostProcessor。

                    ② 如果 BeanFactory 中没用配置 org.springframework.context.event.internalEventListenerProcessor 名称的bean,则使用默认的 EventListenerMethodProcessor。

                    ② 如果 BeanFactory 中没用配置 org.springframework.context.event.internalEventListenerFactory 名称的bean,则使用默认的 DefaultEventListenerFactory。

             3.  创建  ClassPathBeanDefinitionScanner 实例,扫描 @Component, @Repository, @Service, @Controller 配置的工具类。

 

      预处理程序上下文(ConfigurableApplicationContext)。SpringApplication#prepareContext()

        1.  设置上下文环境(ConfigurableApplicationContext) 的环境变量信息。

        2.  处理上下文环境(ConfigurableApplicationContext) 相关信息。默认主要设置 ApplicationConversionService 实例。

        3.  遍历执行 ApplicationContextInitializer 接口实现,进行相关初始化处理。

                   常用的 ApplicationContextInitializer  接口实现类:

                            org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer 

                                     向上下文环境(ConfigurableApplicationContext) 添加(CachingMetadataReaderFactoryPostProcessor) 处理器。
                            org.springframework.boot.context.config.DelegatingApplicationContextInitializer,

                                   读取 context.initializer.classes 配置,委派处理自定义的 ApplicationContextInitializer  实现。
                            org.springframework.boot.context.ContextIdApplicationContextInitializer,

                                   向上下文环境(ConfigurableApplicationContext) 注册 ContextId 实例。
                            org.springframework.boot.devtools.restart.RestartScopeInitializer,

                                   向上下文环境(ConfigurableApplicationContext) 注册 RestartScope 实例。
                            org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener,

                                   添加 ConditionEvaluationReportLoggingListener 监听器。
                            org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,

                                  向上下文环境(ConfigurableApplicationContext) 添加(ConfigurationWarningsPostProcessor) 处理器。
                            org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,

                                  添加 RSocketPortInfoApplicationContextInitializer.Listener 监听器。
                            org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

                                  添加 ServerPortInfoApplicationContextInitializer 监听器。

        4.  执行 SpringApplicationRunListeners#contextPrepared() 方法,触发 ApplicationContextInitializedEvent 事件。

              满足 ApplicationContextInitializedEvent  事件的监听器:

                org.springframework.boot.devtools.restart.RestartApplicationListener, 未满足执行条件,无处理逻辑。
                org.springframework.boot.autoconfigure.BackgroundPreinitializer,  未满足执行条件,无处理逻辑。
                org.springframework.boot.context.config.DelegatingApplicationListener  未满足执行条件,无处理逻辑。

        5.  打印程序启动日志信息。

        6.  设置 beanFactory 信息。注册 ApplicationArguments 和 Banner 的 bean实例。根据配置添加 LazyInitializationBeanFactoryPostProcessor 处理器。

        7.  加载所有 bean 资源配置信息,并转换成 BeanDefinition 配置对象。

                  创建 BeanDefinitionLoader 实例,设置 资源对象, 并创建读取资源的默认实现类, AnnotatedBeanDefinitionReader, XmlBeanDefinitionReader, GroovyBeanDefinitionReader,ClassPathBeanDefinitionScanner。然后根据资源对象的类型,读取资源里面配置的 BeanDefinition  信息。spring boot 默认是使用 AnnotatedBeanDefinitionReader 实现读取资源。

        8.  执行SpringApplicationRunListeners#contextLoaded() 方法,触发ApplicationPreparedEvent 事件。

              满足 ApplicationPreparedEvent 事件的监听器:

                      org.springframework.boot.devtools.restart.RestartApplicationListener, 

                           执行Restarter#prepare(org.springframework.context.ConfigurableApplicationContext) 方法。
                      org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,

                           解析 VCAP(又名 Cloud Foundry)元数据。
                      org.springframework.boot.context.config.ConfigFileApplicationListener,

                           添加配置文件相关的 PropertySourceOrderingPostProcessor 处理器。
                      org.springframework.boot.context.logging.LoggingApplicationListener,

                          注册日志相关的 LogbackLoggingSystem 和 LoggerGroups 的 bean 实例。
                      org.springframework.boot.autoconfigure.BackgroundPreinitializer,  未满足执行条件,无处理逻辑。
                      org.springframework.boot.context.config.DelegatingApplicationListener, 未满足执行条件,无处理逻辑。
                      org.springframework.boot.devtools.logger.DevToolsLogFactory$Listener  日志处理。

 

         执行 started() 方法。SpringApplicationRunListeners#started()

            满足 ApplicationStartedEvent 事件监听器,           

                  org.springframework.boot.devtools.restart.RestartApplicationListener, 未满足执行条件,无处理逻辑。
                  org.springframework.boot.autoconfigure.BackgroundPreinitializer,  未满足执行条件,无处理逻辑。
                  org.springframework.boot.context.config.DelegatingApplicationListener 未满足执行条件,无处理逻辑。

          执行 AvailabilityChangeEvent.publish(context, LivenessState.CORRECT) 方法,触发 AvailabilityChangeEvent 事件:       

                org.springframework.boot.devtools.restart.RestartApplicationListener, 未满足执行条件,无处理逻辑。
                org.springframework.boot.context.config.DelegatingApplicationListener, 未满足执行条件,无处理逻辑。
                org.springframework.boot.availability.ApplicationAvailabilityBean 记录 AvailabilityChangeEvent 事件。

            

       执行 runing() 方法。SpringApplicationRunListeners#running(ConfigurableApplicationContext context)

         满足 ApplicationReadyEvent 事件监听器:  

           org.springframework.boot.devtools.restart.RestartApplicationListener,  调用 Restarter.getInstance().finish() 方法。
           org.springframework.boot.autoconfigure.BackgroundPreinitializer,  检查后台线程早期初始化处理器是否完成,如果没完成则等待。
           org.springframework.boot.context.config.DelegatingApplicationListener, 未满足执行条件,无处理逻辑。
           org.springframework.boot.devtools.autoconfigure.ConditionEvaluationDeltaLoggingListener  重启时相关信息。

     执行 AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC) 方法,触发 AvailabilityChangeEvent 事件:        

         org.springframework.boot.devtools.restart.RestartApplicationListener, 未满足执行条件,无处理逻辑。
         org.springframework.boot.context.config.DelegatingApplicationListener, 未满足执行条件,无处理逻辑。
         org.springframework.boot.availability.ApplicationAvailabilityBean  记录 AvailabilityChangeEvent 事件。

 

      当出现异常,进行异常处理

        SpringApplication#handleRunFailure(ConfigurableApplicationContext context,

                                                           Throwable exception,

                                                          Collection<SpringBootExceptionReporter> exceptionReporters,

                                                         SpringApplicationRunListeners listeners)

        1.  获得退出异常的退出码(exitCode)。如果找到了,则触发  ExitCodeEvent 事件, 并用 SpringBootExceptionHandler 记录退出码信息。

        2.  执行 SpringApplicationRunListeners#failed()方法,触发  ApplicationFailedEvent 事件,进行相关事件处理。

        3.  SpringBootExceptionHandler 记录异常类信息。

 

四. Spring 的 PostProcessor 分析

      Spring 调用 BeanFactoryPostProcessor  处理器,进行 bean 配置的处理。

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors)

SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor,
ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor@7baba5c4,
ConfigFileApplicationListener$PropertySourceOrderingPostProcessor

    (一):依次执行BeanFactory的 BeanDefinitionRegistryPostProcessor 处理器 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法。

          1. SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor  注册在 ConfigurationClassPostProcessor 和 Spring Boot 之间共享元数据的bean对象SharedMetadataReaderFactoryBean。

          2.ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor  检查@ComponentScan 配置是否有问题。即是否配置了 org.springframework 和 org 包扫描路径。

          3. ConfigurationClassPostProcessor  处理注册配置的 BeanDefinition 信息。spring中所有注解配置,都是通过这个类来实现的。                

                  org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
                       org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions(BeanDefinitionRegistry registry)

                       ①   获取当前 BeanDefinitionRegistry 上加载的所有 BeanDefinition 配置。

                       ②   循环处理加载的 BeanDefinition 配置。如果满足指定条件,则将其添加到 待处理配置bean列表中(configCandidates)。

                                  如果 BeanDefinition 实例以及被 ConfigurationClassPostProcessor 类处理,则不进行后续处理。

                                  如果没有经过处理,则判断 BeanDefinition 配置的类是否使用 @Configuration 修饰。或者是否使用 @Component, @ComponentScan, @Import, @ImportResource 修饰,或者方法是否使                            用 @Bean 修饰。

                       ③    根据当前环境,创建 ConfigurationClassParser 实例。

                              ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, 

                                                                       ProblemReporter problemReporter, Environment environment,

                                                                       ResourceLoader resourceLoader, 

                                                                      BeanNameGenerator componentScanBeanNameGenerator,

                                                                      BeanDefinitionRegistry registry)     

                         ④   使用 ConfigurationClassParser  工具类实例,循环处理 @Configuration 修饰的类BeanDefinition 配置。

                                  a. 依次解析 @Component, @PropertySource,@ComponentScan,@ComponentScans,@Import,@ImportResource,@Bean 注解的配置,

                                      或实现 ImportBeanDefinitionRegistrar 接口的配置。

                                  b.  校验 解析的配置。

                                  c.  创建读取 Bean配置的  ConfigurationClassBeanDefinitionReader  实例reader。

                                  d.  使用reader读取 ConfigurationClass 配置的 BeanDefinition 信息。

                                  e.  重新获取 BeanDefinitionRegistry 上加载的所有 BeanDefinition 配置,去掉已经解析过的 @Configuration 配置。

                                  f.  检查是否还有 待处理配置 bean 。如果有则循环 a 至 e 步骤。

 

    (二):依次执行BeanFactory的 BeanFactoryPostProcessor 处理器 BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法   

             SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor,  无处理逻辑
             ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor,   无处理逻辑
             ConfigurationClassPostProcessor   处理配置类。如果配置类 中属性 ConfigurationClassPostProcessor.configurationClass = "full"(即@Configuration(proxyBeanMethods=true)),则将beanClass设置为cglib代理的类。ConfigurationClassEnhancer#enhance(Class<?> configClass, @Nullable ClassLoader classLoader)

 

       ConfigFileApplicationListener$PropertySourceOrderingPostProcessor  无满足条件,无处理逻辑


        PropertySourcesPlaceholderConfigurer  解析 ${...} 配置

            PropertySourcesPlaceholderConfigurer#postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
                 PropertySourcesPlaceholderConfigurer#processProperties(ConfigurableListableBeanFactory, ConfigurablePropertyResolver)
                      PlaceholderConfigurerSupport#doProcessProperties(ConfigurableListableBeanFactory, StringValueResolver)

         1.   创建 BeanDefinitionVisitor 实例visitor。

         2.   依次取出所有 BeanDefinition  配置,使用 visitor 实例解析 BeanDefinition  配置的属性。即将 ${...} 配置替换成实际的值。

         3.   依次取出所有 别名 配置,使用 valueResolver 实例解析 alias, registeredName 值。即将 ${...} 配置替换成实际的值。

         4.   将 valueResolver 解析器添加到 beanFactory 上。


       EventListenerMethodProcessor,  将EventListenerFactory类型bean 取出,添加到  eventListenerFactories 属性上。处理将 @EventListener 修饰的类包装成ApplicationListener 。
       ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor  确保在使用 AOP 时保留 ErrorController MVC bean 的目标类。

 

     (三):在创建bean 对象实例时,再通过 BeanPostProcessor 进行bean对象实例的增强处理。在创建 bean 实例时,有六个位置调用BeanPostProcessor  实现进行bean增强处理。

          1.   开始创建  bean  实例之前,尝试 快捷方式创建 bean 实例。如果创建成功,则创建逻辑不再执行。

                AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                      AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)
                           AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
                                 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
                           AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                                BeanPostProcessor#postProcessAfterInitialization(Object bean, String beanName)

                

               ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor   无处理逻辑
               CommonAnnotationBeanPostProcessor  无处理逻辑
               AutowiredAnnotationBeanPostProcessor  无处理逻辑

               ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor  无处理逻辑

 

             2.   创建 bean 实例后,检查 BeanDefinition 配置是否需要合并。

                AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                      AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                            AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
                                  MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)

            

                 ApplicationListenerDetector, 检查配置的 beanDefinition 是否是 ApplicationListener 类型。如果是,则添加到成员字段上。

                CommonAnnotationBeanPostProcessor  检查 beanType 的字段和方法是否使用 @PostConstruct 和 @PreDestroy标识,如果是,则包装成 LifecycleMetadata 实例,为后续处理进行准备。

                                                                                 检查 beanType 的字段和方法是否使用 @WebServiceRef, @EJB 和 @Resource标识,如果是,则包装成 WebServiceRefElement, EjbRefElement,                                                                                                   ResourceElement 实例,添加到 AutowiredAnnotationBeanPostProcessor#injectionMetadataCache 中为后续依赖注入处理进行准备。    

                AutowiredAnnotationBeanPostProcessor  检查 beanType 的字段和方法是否使用 @Autowired 和 @Value 标识。如果是,则将解析后包装成 AutowiredFieldElement,  AutowiredMethodElement 添加到

                                                                                   AutowiredAnnotationBeanPostProcessor#injectionMetadataCache 中。进行依赖注入管理。

 

             3.   在填充 bean 属性之前,进行 bean 实例后处理。

                AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                      AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                            AbstractAutowireCapableBeanFactory#populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
                                  InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(Object bean, String beanName)

                   默认无满足条件的 InstantiationAwareBeanPostProcessor。

                CommonAnnotationBeanPostProcessor    无处理

                AutowiredAnnotationBeanPostProcessor   无处理

 

              4. 使用 InstantiationAwareBeanPostProcessor 处理器,进行bean 属性的处理

                AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                     AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                          AbstractAutowireCapableBeanFactory#populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
                              InstantiationAwareBeanPostProcessor#postProcessProperties(PropertyValues pvs, Object bean, String beanName)

                   默认无满足条件的 InstantiationAwareBeanPostProcessor。

                  CommonAnnotationBeanPostProcessor  注入 @WebServiceRef, @EJB 和 @Resource 修饰的字段和方法。

                  AutowiredAnnotationBeanPostProcessor    注入  @Autowired 和 @Value  修饰的字段或方法。

 

              5.  在初始化 bean 实例时,进行增强处理

                  AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                        AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                              AbstractAutowireCapableBeanFactory#initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
                                   AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
                                        BeanPostProcessor#postProcessBeforeInitialization(Object bean, String beanName)

               ApplicationContextAwareProcessor 检查 bean 实例是否是Aware 系列接口的实现。当满足条件时,设置相应的环境属性。

               ApplicationListenerDetector  无处理。

               WebApplicationContextServletContextAwareProcessor  判断是否是  ServletContextAware 和 ServletConfigAware 接口实现。是则进行相关属性设置。

               ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor   判断是否是 ImportAware  的实例,如果是则设置 AnnotationMetadata 属性。

               PostProcessorRegistrationDelegate$BeanPostProcessorChecker  无处理逻辑

               ConfigurationPropertiesBindingPostProcessor  检查 bean 是由 @ConfigurationProperties 注解修饰。如果是,则使用 ConfigurationPropertiesBinder#bind(ConfigurationPropertiesBean) 处理。

               CommonAnnotationBeanPostProcessor    获取当前 bean 的 LifecycleMetadata 实例,回调  @PostConstruct 标记的方法。

               AutowiredAnnotationBeanPostProcessor   无处理。

               ErrorPageRegistrarBeanPostProcessor     当bean 是否是 ErrorPageRegistry 实现类时,则进行依次调用 ErrorPageRegistrar#registerErrorPages() 接口。

 

               6.   在完成初始化 bean 实例后,进行增强处理

                     AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                           AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                                 AbstractAutowireCapableBeanFactory#initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
                                      AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                                            BeanPostProcessor#postProcessAfterInitialization(Object bean, String beanName)

             ApplicationContextAwareProcessor  无处理。

            ApplicationListenerDetector  判断是否是 ApplicationListener 的实例,并且是单例模式。如果是,则添加到 监听器(ApplicationListener)列表中。

            WebApplicationContextServletContextAwareProcessor   无处理

            PostProcessorRegistrationDelegate$BeanPostProcessorChecker  检查  BeanPostProcessor 数量。

            ConfigurationPropertiesBindingPostProcessor   无处理

            CommonAnnotationBeanPostProcessor     无处理

            AutowiredAnnotationBeanPostProcessor    无处理

           MethodValidationPostProcessor  检查当前 bean 是否动态代理相关的逻辑。1.当是实现 Advised 接口,则直接返回。2.检查是否配置了AOP增强处理(例如:@Validated ),则生成bean 的动态代理实例。

           AsyncAnnotationBeanPostProcessor

           WebServerFactoryCustomizerBeanPostProcessor   无处理

 

 

 ApplicationContextAwareProcessor,
 WebApplicationContextServletContextAwareProcessor,
 ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor,
 PostProcessorRegistrationDelegate$BeanPostProcessorChecker,
ConfigurationPropertiesBindingPostProcessor(proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false)
 WebServerFactoryCustomizerBeanPostProcessor,
 ErrorPageRegistrarBeanPostProcessor,
 CommonAnnotationBeanPostProcessor,
 AutowiredAnnotationBeanPostProcessor,
 ApplicationListenerDetector
MethodValidationPostProcessor

五. Springboot 读取加载 自动装置配置信息

      主要在启动时,读取所有jar文件中META-INF/spring.factories配置的 org.springframework.boot.autoconfigure.EnableAutoConfiguration 装载类

org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
    org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions(ConfigurableListableBeanFactory beanFactory)
        org.springframework.context.annotation.ConfigurationClassParser#parse(Set<BeanDefinitionHolder>)
             org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#process()
                  org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports()
                      org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping#getImports()
                          org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process()
                              org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry(AnnotationMetadata annotationMetadata)
                                   org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes)
                                          org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getSpringFactoriesLoaderFactoryClass()

 

posted on 2022-04-25 20:34  流羽  阅读(1036)  评论(0编辑  收藏  举报