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(自动注入处理)

publicstaticvoidregisterAnnotationConfigProcessors(BeanDefinitionRegistry registry){

// 调用了registerAnnotationConfigProcessors方法

registerAnnotationConfigProcessors(registry,null);

}

publicstaticSet<BeanDefinitionHolder>registerAnnotationConfigProcessors(

BeanDefinitionRegistry registry,@NullableObject source){

DefaultListableBeanFactory beanFactory =unwrapDefaultListableBeanFactory(registry);

Set<BeanDefinitionHolder> beanDefs =newLinkedHashSet<>(8);

if(!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)){

// 看见没有,在这里注册了ConfigurationClassPostProcessor类。

RootBeanDefinition def =newRootBeanDefinition(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 =newRootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);

def.setSource(source);

// 同时也注册了另一个重要类AutowiredAnnotationBeanPostProcessor

beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));

}

// ...

return beanDefs;

}

    1. 注册配置类的源码流程如下:

publicvoidregisterBean(Class<?> annotatedClass){

doRegisterBean(annotatedClass,null,null,null);

}

<T>voiddoRegisterBean(Class<T> annotatedClass,@NullableSupplier<T> instanceSupplier,@NullableString name,

@NullableClass<?extendsAnnotation>[] qualifiers,BeanDefinitionCustomizer... definitionCustomizers){

// 创建BeanDefinition

AnnotatedGenericBeanDefinition abd =newAnnotatedGenericBeanDefinition(annotatedClass);

// 生成bean name

String beanName =(name !=null? name :this.beanNameGenerator.generateBeanName(abd,this.registry));

AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

// ...省去了其它代码

// 创建BeanDefinitionHolder,它是BeanDefiniton的一个包装类,包含BeanDefiniton对象和它的名字

BeanDefinitionHolder definitionHolder =newBeanDefinitionHolder(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的时候使用



作者:rock_fish


链接:https://www.jianshu.com/p/ebb86320dd0c


来源:简书


著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以上是 springboot注解处理流程 的全部内容, 来源链接: utcz.com/z/514508.html

回到顶部