1

缘由

Spring Framework 提供了除IOC之外的很多有意思的功能,深入研究其技术原理,可在项目技术选型上提供更多的思路和技术把控。Spring Framewrok 代码由大佬精心打磨,可以从功能实现上学习和模仿。另外Spring Framework是Java项目开发的基础,其他技术框架都会基于或者与Spring 兼容,研究其中的技术原理,可快速掌握其他技术框架的技术原理,比如 Spring boot \ Spring cloud...

简述

Spring Framework 出现的背景是,Java 对象之间调用关系复杂,为简化对象调用,Spring Framework 基于Dependency Injection,将对象的控制权转移到BeanFactory,由框架负责对象的生命周期,将对象与Bean进行映射,Bean的生命周期由完善的管理机制。

本文将会根据自己对Spring Framework的理解编辑。

正文

Spring Framework的核心技术非IOC莫属,BeanFactory接口可以将IOC的功能基本体现出来,子接口与子类实现各自的职责,层次清晰,职责明朗,可以作为面向对象的编程范文。

BeanFactory

注释中解释了Spring 的基本行为,基于Bean Definition创建Bean实例,由Bean Factory负责对象的创建、以及属性的赋值。

  1. 注释中提到一个说法,依赖 dependency injection 通常来说是比较好的。凭借 Dependency Injection 以推送的形式去配置应用对象通过setters 或者 constructors,而不是使用任何形式的拉去配置,比如BeanFactory lookup。
  2. BeanFactory会加载来自多种形式配置的 bean definition, 比如 xml 、配置bean的package ,bean definition 如何存储时无所谓的。鼓励支持bean之间引用的实现。
  3. 依赖注入功能是实现BeanFactory接口和子接口。

ListableBeanFactory

BeanFactory接口的扩展,可以列举所有的Bean实例,该接口的实现类要预加载所有单实例Bean.

HierarchicalBeanFactory

允许设置父容器,适用于web环境,Spring 有一个核心BeanFactory 还有一个Web BeanFactory.

ApplicationContext

BeanFactory定义了Spring Framework的基本思想和特性,解决了项目开发中核心痛点,另外还有其他的特性增加开发工作中的便利性,比如国际化、事件、资源加载等功能。

继承下列所有接口:

  1. EnvironmentCapable
  2. ListableBeanFactory
  3. HierarchicalBeanFactory
  4. MessageSource
  5. ApplicationEventPublisher
  6. ResourcePatternResolver

ConfigureableApplicationContext

BeanFactory接口的扩展,增加BeanFactory的配置能力,接口中的方法仅在容器启动或者销毁时使用,比如启动时需要的BeanFactoryPostProcessor, ApplicationListener, ResourceLoader ...


以上接口定义Spring Framework 框架的基本行为。

AbstractApplicationContext

ApplicationContext接口的抽象实现,已实现主要的Spring Frameword 特性,ApplicationContext接口定义的功能,都可以在此类中提供默认实现。

浏览源码,大致功能如下:

  1. 构造器中可设置 resourcePatternResolver 属性,创建PathMatchingResourcePatternResolver 对象。
  2. 构造器中可设置父容器,并融合父容器中的环境变量。
  3. 实现 ApplicationContext 中的接口,比如 publishEvent setStartupDate ...
  4. 实现 ConfigurationApplicationContext 中的接口,比如 addBeanFactoryPostProcessor addApplicationListener refresh() registerShutdownHook close ...

// refresh 方法涉及到的方法。
prepareRefresh prepareBeanFactory postProcessBeanFactory registryBeanPostProcessors invokeBeanFactoryPostProcessors initMessageSource initApplicationEventMulticaster initLifecycleProcessor registerListeners finishBeanFactoryInitialization finishRefresh

  1. 实现 BeanFactory 中的接口,比如 getBean isSingleton isTypeMatch
  2. 实现 ListableBeanFactory 中的接口,比如 containsBeanDefinition getBeanDefinitionNames findAnnotationOnBean ..
  3. 实现 HierarchicalBeanFactory 中的接口,比如 getParentBeanFactory getInternalParentBeanFactory ...
  4. 实现 MessageSource 中的接口,比如 getMessage getMessageSource ...
  5. 实现 ResourcePatternResolver 中的接口,比如getResources
  6. 实现 Lifecycle 中的接口,比如start stop isRunning
  7. 抽象方法 refreshBeanFactory ...

GenericApplicationContext

完整的ApplicationContext实现,实现了BeanDefinitionRegistry接口的方法,拥有注册BeanDefinition的能力,可以覆盖一些BeanFactory的属性。

  1. 构造器中创建 DefaultListableBeanFactory。
  2. 配置BeanFactory allowBeanDefinitionOverriding bean定义覆盖的问题 allowEagerClassLoading 是否加载标记为懒加载的类。
  3. 实现 AbstractApplicationContext 中的虚拟方法 refreshBeanFactory getBeanFactory ...
  4. 实现 BeanDefinitionRegistry 接口,比如 registerBeanDefinition isBeanNameInUse
  5. 手动注册Bean registerBean.

AnnotationConfigApplicationContext

接收 component class 、Configuration annotated class,@Component JSR330 javax.inject annotation.
允许一个接一个使用register方法注册类,扫描class path。Bean annotation 可以被后续的覆盖。

构造器中初始化 AnnotatedBeanDefinitionReader ClassPathBeanDefinitionScanner。或者手动注册一个启动类,并启动容器启动操作 refresh.

DefaultListableBeanFactory

一个很核心的类,可以说是IOC功能的承载者。继承抽象类 AbstractAutowireCapableBeanFactory。

  1. 实现 BeanFactory 剩余的接口实现 getBean getBeanProvider resolveBean ...
  2. 实现 ListableBeanFactory 接口,比如 getBeanDefinitionNames containsBeanDefinition ...
  3. 实现 ConfigurableListableBeanFactory 接口,比如 registerResolvableDependency isAutowireCandidate preInstantiateSingletons
  4. 实现 BeanDefinitionRegistry 接口,比如 registerBeanDefinition registerSingleton
  5. 处理依赖的一些方法。resolveNamedBean resolveDependency doResolveDependency resolveMultipleBeans

AbstractAutowireCapableBeanFactory

实现默认的Bean创建,具有RootBeanDefinition指定的全部功能。
使用构造器解析提供bean创建,属性填充,wiring,初始化。
支持构造器注入、名字或类型注入。
没有任何的bean注册能力。


通过上述的接口和类的介绍,BeanFactory的子类和相关子接口有个了大致的了解,使用由上至下的顺序介绍了spring Ioc 容器的功能,其中还有一些类或者接口没有介绍到,可以在源码中进入详细了解。

Spring Framework 启动流程。

Spring的启动流程可以简单描述为启动框架的提供功能,加载并初始化开发人员定义的类。

Spring Framework 目前几乎所有开发人员都会采用基于注解的形式开发应用。首先会使用new AnnotationConfigApplicationContext() 启动一个Spring Application Context。

AnnotationConfigApplicationContext 是继承了 GenericApplicationContext 和 AbstractApplicationContext,加载子类时会先加载父类,并使用父类的无参构造或者指定的有参构造创建父类。GenericApplicationContext的无参构造器中会创建一个DefaultListableBeanFactory,对于DefaultListableBeanFactory的父类AbstractAutowireCapableBeanFactory 同样也会被加载到Jvm中,创建对应Class对象。AbstractApplicationContext是一个抽象类,不过其中静态属性和静态方法也会被初始化,创建 PathMatchingResourcePatternResolver 作为默认的 ResourcePatternResolver。

初始化完父类后,就会执行 AnnotationConfigApplicationContext 无参构造器,创建 AnnotatedBeanDefinitionReader 和 ClassPathBeanDefininationScanner。

AnnotatedBeanDefinitionReader的构造器中,除了一些赋值外,会执行 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 这行代码对基于注解的应用尤为的至关重要。其中会将一批框架提供的配置类包装为Bean Definition放入BeanFactory,其中包括:

  • ConfigurationClassPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • EventListenerMethodProcessor
  • DefaultEventListenerFactory
  • AnnotationAwareOrderComparator
  • ContextAnnotationAutowireCandidateResolver
    大多是一些后置处理器和工具类。

ClassPathBeanDefininationScanner主要是用来扫描classpath路径下类,继承 ClassPathScanningCandidateComponentProvider 提供扫描过程中的一些配置。


以上就是AnnotationConfigApplicationContext对象创建的流程,即将进入 AbstractApplicationContext.refresh() 方法。

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            } catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + 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();
                contextRefresh.end();
            }
        }
    }

这是一个Spring context的启动流程,有些context可以启动多次,有些只能启动一次,另外也会提供取消启动和重新启动的API.

prepareRefresh()

准备启动Spring context

  1. 设置启动时间
  2. 激活工作标识
  3. 初始化context中所有的 placeholder property sources
  4. 验证启动比如设置的变量
  5. 保存重新启动前的ApplicationListener

obtainFreshBeanFactory()

通知子类刷新内部的BeanFactory,其中子类比较关注 GenericApplicationContext。

  1. 原子更新刷新标识。
  2. 设置BeanFactory的唯一标识。

prepareBeanFactory()

准备上下文中的BeanFactory,配置标准context中的classLoader 和一些 PostProcessors

  1. 若要使用SPEL,则配置StandardBeanExpressionResolver。
  2. 增加ResourceEditorRegistrar 到 propertyEditorRegistrar。
  3. 配置分析依赖时需要忽略的接口 EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware
  4. 配置 ApplicationContextAwareProcessor ApplicationListenerDetector ApplicationEventPublisherAware MessageSourceAware ApplicationContextAware ApplicationStartupAware,这些接口需要框架提供支持,不需要在依赖注入时处理。
  5. 若要使用加载时创建代理,则配置LoadTimeWeaverAwareProcessor ContextTypeMatchClassLoader
  6. 配置处理依赖注入时需要注入的对象,比如Bean需要一个 ApplicationContext,在进行注入时会将配置的对象注入到Bean当中。
  7. 注册几个环境变量相关的Bean,systemProperties systemEnvironment。

postProcessBeanFactory()

处理 postProcessBeanFactory,暂未发现有效调用,是个空方法。

invokeBeanFactoryPostProcessors()

调用已注册的postProcessBeanFactory。

使用委托模式将PostProcessor的注册工作放置到 PostProcessorRegistrationDelegate中,调用 invokeBeanFactoryPostProcessors(),处理context中的BeanFactoryPostProcessor。
判断BeanFactory是否继承BeanDefinitionRegistry接口,没有继承就会直接调用 invokeBeanFactoryPostProcessors处理context中的beanFactoryPostProcessors。若继承BeanDefinitionRegistry:

  1. 对context中的beanFactoryPostProcessors,进行分类,属于BeanDefinitionRegistryPostProcessor的 postProcessor 执行 postProcessBeanDefinitionRegistry()。
  2. 获取BeanFactory中的 BeanDefinitionRegistryPostProcessor.class 类型的BeanName数组,接下来就会遍历BeanName数组。
  3. 若bean实现了 PriorityOrdered \ Ordered 类,就会调用 invokeBeanDefinitionRegistryPostProcessors 处理BeanDefinition的注册工作。逻辑较多,独立在后续说明。
  4. 接着会调用 invokeBeanFactoryPostProcessors 执行 postProcessBeanFactory().
  5. 对@Configuration的类创建代理,并注册 ImportAwareBeanPostProcessor 到 BeanPostProcessor 的 BeanPostProcessor.
  6. 对BeanFactoryPostProcessors进行分类和排序 invokeBeanFactoryPostProcessors.

此过程处理的postProcessors,可以是开发人员定义的,也有框架指定的。上面提到过:
AnnotatedBeanDefinitionReader的构造器中,除了一些赋值外,会执行 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 将处理 context 环境中开发人员定义的类 Service Controller ... ConfigurationClassPostProcessor 注入到 BeanFactory中。

registerBeanPostProcessors()

注册BeanPostProcessors 去拦截Bean的创建。

  1. PostProcessorRegistrationDelegate.registerBeanPostProcessors();
  2. 将BeanFactory中的 BeanPostProcessor BeanDefinition 转换为 BeanFactory的 BeanPostProcessor.
  3. 转换过程中会根据BeanDefiniton上面的Order \ PriorityOrdered 先排序再处理。

initMessageSource()

初始化context中的国际化。

过程和centext event 初始化过程相似,先检查 beanFactory 中的 MESSAGE_SOURCE_BEAN_NAME,若没有此BeanDefinition 就会使用默认实现 DelegatingMessageSource 并以单实例的方式注册到 context。另外会处理父子MessageSource,设置子MessageSource的时候会检查并设置父MessageSource。

initApplicationEventMulticaster()

初始化context中的事件机制。

BeanFactory中若有 APPLICATION_EVENT_MULTICASTER_BEAN_NAME BeanDefinition,就会采用Bean创建的模式为 context 中的applicationEventMulticaster 赋值,可以利用此特性去覆盖框架提供的默认实现,只需要自己实现的类被context 扫描到就行。
若没有的话就会使用默认实现 SimpleApplicationEventMulticaster ,并将对象以单实例的方式注入到 context.

onRefresh()

初始化在特定的子context中的特定Bean。空实现。

registerListeners()

检查context中的所有Listener,并注册他们。

首先会注册静态的Listener,接着会获取 BeanFactory 中的 ApplicationListener, 注意此处并不会对获取到BeanDefinition 进行初始化,而是将Beanname 放入到 applicationEventMulticaster的 ApplicationListenerBean 中。最后会检查是否有一批早期事件需要发布,需要的话会直接发布出去。

finishBeanFactoryInitialization()

实例化所有非懒加载的单实例Bean。

在BeanFactory走过了:

  1. 执行 BeanFactoryPostProcessors
  2. 注册BeanPostProcessors
  3. 初始化国际化、事件派发
  4. 注册context中的事件监听器

Context 中的BeanFactory 的初始化工作进入了尾声阶段,此时BeanFactory中的Bean实例全部是使用registrySingleton()注册,扫描到的组件并没有实例化,实例化工作集中在本方法中进行。

首先需要设置BeanFactory中的 embeddedValueResolver 处理注解中需要处理的placeholders.
接着是LoadTimeWeaverAware接口的子类Bean创建,先加载此接口的子类Bean,可以早点注册 transformers 。
停止使用BeanFactory中的临时的类加载器。
可以缓存所有BeanDefinition metadata,但是不能发生更改其中的内容。
开始初始化所有的非懒加载的单实例bean.

  1. 创建 beanDefinitionNames 副本,在副本上迭代处理BeanDefinition,允许在Bean创建过程中执行init methods是注册新的BeanDefinition.
  2. 触发所有非懒加载的单例Bean。

    1. 合并BeanDefinition。getMergedLocalBeanDefinition()
    2. 只处理非抽象类 & 单例 & 非懒加载的 BeanDefinition.
    3. 判断是否属于factoryBean。isFactoryBean()
    4. 先分析非factoryBean的情况,FactoryBean的逻辑部分会在后续补充。
    5. 进入AbstractBeanFactory中,创建Bean.
    6. 调用getBean() -> doGetBean() .
    7. transformedBeanName() 转换BeanName,转换bean aliases为一个规范的BeanName。
    8. 检查bean是否已存在于手动注册的单例缓存中,可能是完全创建的状态,也许是正在创建状态。
    9. 获取前期手动注册的单例Bean, 调用 getObjectForBeanInstance() 就可以返回BeanInstance.
    10. 若前期没有注册过BeanInstance,就进入下面的逻辑。

      1. 检查当前需要创建的Bean是多例Bean的话直接抛错。
      2. 检查父BeanFactory是否为空,并且父Bean Factory中包含此BeanDefinition.就会调用父Bean Factory的getBean(),去创建BeanInstance.
      3. 获取 BeanDefinition 的依赖 mbd.getDependsOn()。遍历依赖项 逐个先创建依赖项。
      4. 接着创建单例Bean的执行处理。进入 getSingleton().
      5. 从singletonObjects中获取是否已创建BeanInstance.
      6. 检查是否BeanSingleton正在销毁,若是则直接抛出异常。
      7. 开始执行 singletonFactory.getObject()。调用doGetBean中的匿名接口ObjectFactory。
      8. getSingleton()方法主要是控制BeanInstance的创建,加锁和创建的条件判断。
      9. 现在开始进入 AbstractAutowireCapableBeanFactory.createBean()方法。
      10. 第一步解析BeanDefinition中的BeanClass,加载BeanClass文件,获得Class对象。并创建BeanDefinition的本地变量,将Class对象设置进去。
      11. 第二步验证并准备BeanDefinition中重载方法的状态。
      12. 第三步应用BeanInstance Before Post Processor,判断BeanFactory中是否有 InstantiationAwareBeanPostProcessor 子类存在。若没有直接返回。

        1. 调用 applyBeanPostProcessorsBeforeInstantiation,执行实现类的 postProcessBeforeInstantiation().
        2. InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 有个默认实现先调用, 空方法而已。
        3. AbstractAutoProxyCreator#postProcessBeforeInstantiation,此方法会创建代理,详细内容可在后续中分析。
      13. 进入同类的doCreateBean()。
      14. 进入同类的createBeanInstance()。为指定的Bean创建Instance,使用合适的instance策略:工厂方法、构造装配、无参构造。

        1. 确保已执行resolveBeanClass。若Bean calss 不是public 直接抛错。
        2. 获取BeanDefinition.getInstanceSupplier() -> obtainFromSupplier()获取Instance.
        3. 获取BeanDefinition.getFactoryMethodName() -> instantiateUsingFactoryMethod() 工厂方法获取Instance。
        4. determineConstructorsFromBeanPostProcessors() 推断构造 -> autowireConstructor() 构造创建。
        5. 未指定处理,就使用无参构造,进入 instantiateBean().
        6. getInstantiationStrategy().instantiate() 使用无参构造创建Instance,BeanUtils.instantiateClass()返回无参构建的Instance Wrapper.
      15. applyMergedBeanDefinitionPostProcessors -> postProcessMergedBeanDefinition ->

        1. ApplicationListenerDetector#postProcessMergedBeanDefinition
        2. AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
        3. CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
        4. 执行上述的三个实现方法。
      16. 有个三个条件,创建的是单例Bean,context允许循环引用,Bean正在实例化,若三个条件全部符合则执行 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 此方法最终会执行 singletonFactories.put 方法。
      17. 开始初始化BeanInstance. 先属性填充,再类初始化。
      18. 属性填充会执行 InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation() 实现类去修改属性被赋值之前的Bean状态。
      19. InstantiationAwareBeanPostProcessor.postProcessProperties().
      20. 执行 aware 的注入 invokeAwareMethods()
      21. applyBeanPostProcessorsBeforeInitialization() postProcessBeforeInitialization(),执行初始化前回调。
      22. 调用 init method
      23. applyBeanPostProcessorsAfterInitialization() postProcessAfterInitialization(),执行初始化后回调。
  3. 触发所有应用Bean的初始化后置后调。
    SmartInitializingSingleton.afterSingletonsInstantiated(),通知所有单例Bean已被创建完成。

finishRefresh()

发布事件。


扫描BeanDefinition的过程分析。

ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()

  1. 检查是否已执行过,不能重复执行。
  2. 进入 processConfigBeanDefinitions()。
  3. 获取Context中被@Configuration标注的类。

    1. 判断BeanDefinition是否拥有属性 ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE,作为已处理的标识。
    2. 借助工具类判断 ConfigurationClassUtils.checkConfigurationClassCandidate()

      1. BeanDefinition中有BeanClassName属性的,没有FactoryMethodName的。
      2. 获取BeanDefinition中的AnnotationMetadata,可通过AnnotationMetadata.introspect(beanClass) metadataReaderFactory.getMetadataReader(className) 获取。
      3. AnnotationMetadata 中有设置 @Configuration注解的并且注解的属性 proxyBeanMethods为TRUE的。可以作为 full configuration 进行后续的 parse处理。
      4. 那些有 AnnotationMetadata 或者有 Component ComponentScan Import ImportResource 的注解 或者 有类中有方法使用@Bean BeanDefinition 就是一个 lite configuration 类。可会进行后续的 parse处理。
      5. 若AnnotationMetadata中有Order注解,会设置到BeanDefinition中。
      1. 将符合条件的BeanDefinition收集起来。
  4. 对获取到的BeanDefinition进行排序。
  5. 获取并支持定制 componentScanBeanNameGenerator importBeanNameGenerator
  6. 检查并设置 StandardEnvironment
  7. 开始 parse @Configuration标识的类(BeanDefinition)

    1. 创建 ConfigurationClassParser 对象。
    2. 进入 processConfigurationClass() 开始进行解析工作。
    3. 进入 ConditionEvaluator.shouldSkip(),会对@Condition注解进行解析判断是否需要解析此Bean。
    4. 使用反射技术根据 className 转化为 SourceClass.
    5. 递归调用 doProcessConfiguration(SourceClass)。
    6. processMemberClasses() 处理标有 @Component 注解的内部类。

      1. 解析内部类是否有被@Configuration的,会直接调用 processConfigurationClass 进行解析。
    7. processPropertySource() 处理标有 @PropertySource 注解的类。

      1. AnnotationConfigUtils.attributesForRepeatable() 解析出类上的@PropertySource数组,逐个处理。
      2. 当前 environment 必须是 ConfigurableEnvironment 的子类。
      3. 获取注解中的 name \ encoding \ value \ ignoreResourceNotFound \ factory。
      4. 将加载到的信息放到当前环境当中。
    8. ComponentScanAnnotationParser.parse() 处理标有 @ComponentScan 注解的类。

      1. 创建 ClassPathBeanDefinitionScanner 对象。
      2. 设置 BeanNameGenerator \ ScopedProxyMode \ ScopeMetadataResolver \ ResourcePattern \ IncludeFilter \ ExcludeFilter \ BeanDefinitionDefaults .
      3. 解析注解中的 basePackages \ basePackageClasses .
      4. 进入 doScan().
      5. 加载每个 package,将获取到的 metadataReader 作为创建 ScannedGenericBeanDefinition 的参数。
      6. 判断 ScannedGenericBeanDefinition 是否有被@Component注解,符合的放入方法结果集中。
      7. 遍历结果集。
      8. 判断是否实现 AbstractBeanDefinition,调用postProcessBeanDefinition进行处理。
      9. 判断是否实现 AnnotatedBeanDefinition,调用AnnotationConfigUtils.processCommonDefinitionAnnotations()进行处理。
      10. 根据BeanDefinition的冲突处理结果注册BeanDefinition.
      11. 从加载到BeanDefinition中过滤是否有@Configuration标注的类,有的话直接调用parse().
    9. processImports() 处理标有 @Import 注解的类。

      1. 判断是否有循环导入的问题
      2. 处理导入的类实现ImportSelector 接口

        1. 加载被导入的类。
        2. ParserStrategyUtils.instantiateClass() 将注解解析为 ImportSelector 对象 selector。
        3. 若 selector 实现了 DeferredImportSelector,直接放入deferredImportSelectorHandler。
        4. 递归处理导入类上的@Import。
      3. 处理导入的类实现ImportBeanDefinitionRegistrar 接口

        1. 加载被导入的类。
        2. ParserStrategyUtils.instantiateClass() 将注解解析为 ImportBeanDefinitionRegistrar 对象 registrar。
        3. 添加到 ImportBeanDefinitionRegistrar 中,在@Configuration注解解析完成后再进行加载。
      4. 处理导入的其他类

        1. 直接使用 processConfigurationClass 处理。
    10. addImportedResource() 处理标有 @ImportResource 注解的类。

      1. AnnotationConfigUtils.attributesFor() 解析出 AnnotationAttributes importResource 。
      2. 将解析出的resource 放入 ImportedResource 中。
    11. addBeanMethod() 处理标有 @Bean 注解的方法。

      1. 获取类中使用@Bean的方法 使用Java反射和ASM获取两遍,并进行比较方法数量和方法名字的比较。
      2. 比较通过的方法放入结果集中。
      3. 将结果集逐个放入BeanMethod
    12. processInterfaces() 处理接口的默认方法。

      1. 处理继承的抽象类非抽象方法或者接口的默认方法
      2. 将父类或者实现的接口中的@Bean标注的方法放入 BeanMethod
      3. 循环处理父类或者父接口.
    13. 解析 superclass.

      1. 处理父类,直接返回循环处理.
  8. this.deferredImportSelectorHandler.process() 开始处理延迟导入队列.

    1. 将队列中的ImportSelector逐个放入 DeferredImportSelectorGroupingHandler.registry()
    2. 实现逻辑较复杂,后续会继续分析.
  9. ConfigurationClassBeanDefinitionReader.loadBeanDefinitions()

    1. registerBeanDefinitionForImportedConfigurationClass

      1. new AnnotatedGenericBeanDefinition(metadata) 构建 BeanDefinition 对象.
      2. 获取 BeanDefinition 中的 scopeMetadata, 经 scopeMetadataResolver.resolveScopeMetadata()处理 设置BeanDefinition的scope
      3. importBeanNameGenerator.generateBeanName() 生成BeanName.
      4. AnnotationConfigUtils.processCommonDefinitionAnnotations()
      5. 注册BeanDefinition.
    2. loadBeanDefinitionsForBeanMethod
    3. loadBeanDefinitionsFromImportedResources
    4. loadBeanDefinitionsFromRegistrars
  10. 对比parse前后的registry中的BeanDefinition数量,将未处理的BeanDefiniton继续处理.
  11. Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes

以上就是对SpringFramework IOC部分的大致流程解析,其中有不少的知识点没有详细分析,后续会基于Spring启动流程中某一个知识点深入分析。


Mario
56 声望5 粉丝

方向大于努力,选择方向总有个期限,过了期限还要再考虑方向问题,岂不是自增烦恼