springboot 注解处理流程


传送:

Spring大观园,我有过的困惑或许你也有!


几个关键类

BeanDefinition

是一个接口,实现有RootBeanDefination,AnnotatedGenericBeanDefinition等。
用来存储Bean定义的一些信息的,比如Class,Scope,init-methon,等等。

BeanDefinitionHolder

这是BeanDefination的包装类,用来存储BeanDefinition,name(bean名称)以及aliases(bean别名)等

BeanFactory

BeanFactory 创建和管理bean,同时作为bean的容器存放bean的定义以及bean实例等。AbstractBeanFactory继承了BeanFactory接口,并且实现了大部分BeanFactory的功能,通过其getBean方法创建bean,没有就创建,并缓存,已创建了就直接返回,所以名字叫getBean,其内部还有createBean的方法来创建bean。

Environment

提供了应用所需要的运行时环境信息,如各种propertySource.

AnnotatedBeanDefinitionReader

负责创建bean定义并注册到容器中,其主动注册了几个核心处理器(BeanFactoryPostProcessor),如ConfigurationClassPostProcessor 实现配置类解析,组件扫描。

AnnotationConfigApplicationContext

基于注解的容器类,它实现了BeanFactory和BeanDefinitionRegistry两个接口,拥有Bean对象的管理和BeanDefinition注册功能。同时这个类中有DefaultListableBeanFactory, xxxEnvironment 和AnnotatedBeanDefinitionReader等等,协调这几个对象,让他们各司其职,协同工作完成spring的初始化和bean的创建。
AnnotationConfigApplicationContext的实际的对象管理和BeanDefinition注册是委托DefaultListableBeanFactory(也实现了BeanFactory和BeanDefinitionRegistry接口)来实现的。

知晓bean创建 两步走

spring的ioc有自己的一套bean管理机制,在他的内部创建对象除了class信息之外还要其他信息,如是否单例,是否延迟初始化等。通过bean定义(BeanDefinition)来封装class以及其他的一些信息。
所以bean实例的创建一般是2步
第一步是创建bean的定义(BeanDefinition)对象,放入到容器中,
第二部是根据bean的定义信息创建bean的实例对象,根据条件放入容器中。
创建bean的实例对象有分几个步骤

  1. 从BeanDefinition 中拿到Class信息
  2. 反射的方式 实例化 Class 得到一个对象实例
  3. 经历spring中配置的若干个创建bean的几个步骤,对对象实例进行操作后完成bean的创建。这几个步骤是bean的整个生命周期的一部分;
理解Bean和对象的区别
实例 类型
jvm 对象实例 class类
spring bean beanDefinition

beanDefinition(bean定义) 是bean的描述,拥有许多bean的描述信息(包括了class信息),jvm层面反射创建对象(对象由jvm管理),spring需要再对这个反射创建的对象再做一些操作后这个对象才叫做bean(bean由spring管理);由此看来bean创建与对象创建的区别就是多了几次spring规定的操作,这些操作构成了bean的生命周期。

BeanFactoryPostProcessor和BeanPostProcessor

spring两步走,创建bean定义,根据bean定义创建bean;

  • BeanFactoryPostProcessor的操作对象是bean工厂,执行的操作是往工厂中添加BeanDefinition。
  • BeanPostProcessor的操作对象是bean,作用于bean创建的生命周期中。

Spring中Bean大致可以分为两类,应用类Bean(被应用程序使用)和功能性Bean(被Spring使用)。从上边介绍可知BeanFactoryPostProcessor和BeanPostProcessor的实现类就是功能性bean,给spring提供服务,spring使用他们之前必然通过getBean的方式创建他们.

  • BeanFactoryPostProcessor,在refresh方法中调用invokeBeanFactoryPostProcessors方法时创建,
  • BeanPostProcessor的实现bean,在registerBeanPostProcessors方法中创建.
  • 其它应用类Bean,在默认的finishBeanFactoryInitialization方法中创建.
AnnotatedBeanDefinitionReader
  • 在构造函数中做了两件关键事宜:
    1.BeanFactory中注册与注解相关的xxxProcessor处理器,用于解析配置类,扫描bean
    2.注册配置类
    表面分别来看:
  • 1.注册处理器: xxxApplicationContext的构造方法中会创建AnnotatedBeanDefinitionReader,reader的构造函数中 通过AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)往BeanDefinitionRegistry 中注册 注解配置相关的 processors,重点看ConfigurationClassPostProcessor (解析配置类,扫描bean),AutowiredAnnotationBeanPostProcessor(自动注入处理)
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        // 调用了registerAnnotationConfigProcessors方法
        registerAnnotationConfigProcessors(registry, null);
    }

public static Set registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);    

        Set beanDefs = new LinkedHashSet<>(8);

        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            // 看见没有,在这里注册了ConfigurationClassPostProcessor类。
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 主要是调用了registerPostProcessor来进行注册的。
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 同时也注册了另一个重要类AutowiredAnnotationBeanPostProcessor
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
        // ...

        return beanDefs;
    }
    1. 注册配置类的源码流程如下:
    public void registerBean(Class annotatedClass) {
        doRegisterBean(annotatedClass, null, null, null);
    }


     void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name,
            @Nullable Class[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

        // 创建BeanDefinition
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
        // 生成bean name
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        
        // ...省去了其它代码

        // 创建BeanDefinitionHolder,它是BeanDefiniton的一个包装类,包含BeanDefiniton对象和它的名字
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        // 最后调用registerBeanDefinition
        // 其内部是调用beanFactory的registerBeanDefinition,代码如下:
        // this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
        //上文说过,AnnotationConfigApplicationContext是委托DefaultListableBeanFactory来注册BeanDefinition和管理Bean的
        //DefaultListableBeanFactory中的registerBeanDefinition实现为
        //this.beanDefinitionMap.put(beanName, beanDefinition);
        //可以看出,最终是将beanDefinition放到beanDefinitionMap中。所有的beanDefinition都会放到这个map中,以beanName为主键。如果一个beanDefinition有多个别名,那个它会被注册多次。
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    } 
!!!小结
  1. AnnotationConfigApplicationContext通过AnnotatedBeanDefinitionReader
    1.1 注册几个核心xxxprocessor如ConfigurationClassPostProcessor;
    1.2 注册主配置类,

  2. 其内部是委托DefaultListableBeanFactory完成BeanDefinition的注册,

  3. 注册的结果是BeanDefinition被存储在一个Map中,以beanName为key,以BeanDefinition对象为值。

  4. spring通过BeanFactoryPostProcessor开放接口,提供了参与操作beanFactory,注册(修改)BeanDefinition的机会。
    4.1 BeanFactoryPostProcessor调用时机在方法invokeBeanFactoryPostProcessors中, 通过对 所有BeanFactoryPostProcessor实现类的实例化和方法调用,往容器中注册了所有的BeanDefinition;尤其是 ConfigurationClassPostProcessor实现了我们最关注的基于注解的配置类解析,bean扫描等功能)

  5. spring通过BeanPostProcessor开放接口,提供了参与bean构建的机会。
    5.1 在registerBeanPostProcessors(beanFactory)注册,
    5.2 在finishBeanFactoryInitialization(beanFactory)实例化Bean的时候使用


后续还有。。。

你可能感兴趣的:(springboot 注解处理流程)