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的实例对象有分几个步骤
- 从BeanDefinition 中拿到Class信息
- 反射的方式 实例化 Class 得到一个对象实例
- 经历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;
}
- 注册配置类的源码流程如下:
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);
}
!!!小结
AnnotationConfigApplicationContext通过AnnotatedBeanDefinitionReader
1.1 注册几个核心xxxprocessor如ConfigurationClassPostProcessor;
1.2 注册主配置类,其内部是委托DefaultListableBeanFactory完成BeanDefinition的注册,
注册的结果是BeanDefinition被存储在一个Map中,以beanName为key,以BeanDefinition对象为值。
spring通过BeanFactoryPostProcessor开放接口,提供了参与操作beanFactory,注册(修改)BeanDefinition的机会。
4.1 BeanFactoryPostProcessor调用时机在方法invokeBeanFactoryPostProcessors中, 通过对 所有BeanFactoryPostProcessor实现类的实例化和方法调用,往容器中注册了所有的BeanDefinition;尤其是 ConfigurationClassPostProcessor实现了我们最关注的基于注解的配置类解析,bean扫描等功能)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