spring容器启动及bean的创建过程
2021-04-05 11:23:49 9 举报
spring容器启动过程bean的解析、加载、创建
作者其他创作
大纲/内容
判定: FactoryBean类型
实例化ApplicationEventMulticaster用来存储并执行 ApplicationListener
实例化BeanPostProcesser,排序后保存在容器中
属性赋值: populateBean
封装一个执行AbstractAutoProxyCreator.getEarlyBeanReference方法来判定创建proxy_bean的过程ObjectFactory到第三级缓存singletonFactories中.
DefaultSingletonBeanRegistry.beforeSingletonCreation
创建 单例 & 非懒加载 & 非抽象 的Bean AbstractApplicationContext.finishBeanFactoryInitialization -> DefaultListableBeanFactory.preInstantiateSingletons -> AbstractBeanFactory.getBean -> AbstractBeanFactory.doGetBean
判定:对象为空
Populate
回调处理BeanFactory。eg. 触发执行AnnotationConfigServletWebServerApplicationContext.postProcessBeanFactory扫描指定包路径下的类
返回代理对象proxy_bean
InstantiationAwareBeanPostProcessor.postProcessProperties
return
onRefresh
这个阶段被解析出来的BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor也随后就会被实例化并排序,执行接口方法
标记到“正在创建池”singletonsCurrentlyInCreation.历史已经标记过的会抛出异常BeanCurrentlyInCreationException(这也是不支持【构造器依赖】的原因)
从“正在创建池”singletonsCurrentlyInCreation中移除
invokeInitMethods
Initialization
这里当做bean已经创建了实例,执行初始化initializeBean逻辑
给BeanFactory容器初始配置默认的BeanPostProcessor(ApplicationContextAwareProcessor)、BeanClassLoader、系统参数bean等
ConfigurationClassPostProcessor首先扫描启动类(ComponentScan)所在包(含子包)下的类,随后解析@Import的各资源配置类,得到并创建真实需要被引用的类的BeanDefinition,保存在容器中。
AbstractBeanFactory.resolveBeanClass
resolveBeforeInstantiation
createBeanInstance
保证被引用时指向的是同一个实例
触发执行ConfigurableListableBeanFactory.preInstantiateSingletons()来创建 单例 & 非懒加载 & 非抽象 的Bean
false
true
执行到这,对于bean的属性处理已经完成
AbstractBeanFactory.getObjectForBeanInstance
doCreateBean
执行BeanFactoryPostProcesser逻辑。先invokeBeanDefinitionRegistryPostProcessors -> 后invokeBeanFactoryPostProcessors 。此时会创建这两类接口的实例,排序后执行其接口方法
DefaultSingletonBeanRegistry.addSingleton
通过ApplicationEventMulticaster向ApplicationListener发送ContextRefreshedEvent事件;同时这个事件也会发送给父容器处理。此时RefreshScope会接收到该事件,开始实例化它管理的bean。
若是本线程执行 ObjectFactory.getObject() 创建而来的对象。从缓存 singletonFactories(三)、earlySingletonObjects(二)移出到singletonObjects(一)里
finishBeanFactoryInitialization
给BeanWrapper设置属性值
invokeAwareMethods
判定单例是否提前暴露:单例 && 支持循环引用 && 被标记在“正在创建池”
所有模式执行到最后还需要再次判定FactoryBean
DefaultSingletonBeanRegistry.afterSingletonCreation
registerDisposableBeanIfNecessary
确定bean的Class
ObjectFactory.getObject()
finishRefresh
触发执行ServletWebServerApplicationContext.onRefresh()来创建WebServer(TomcatWebServer),这个过程里会给ServletContext里注入Servlet、Filter. eg. DispatcherServletRegistrationBean -> DispatcherServlet
FactoryBean获取真实Bean实例: AbstractBeanFactory.getObjectForBeanInstance
依据BeanDefinition实例化,返回BeanWrapper对象
向 ApplicationEventMulticaster 注册 ApplicationListener
这里常碰到的是:1、AutowiredAnnotationBeanPostProcessor 归集 @Value和@Autowired修饰的方法和属性的描述InjectionMetadata2、CommonAnnotationBeanPostProcessor处理@Resource修饰的方法和属性的描述InjectionMetadata
初始化: initializeBean
判定:二级缓存earlySingletonObjects里是否有提前引入对象
applyBeanPostProcessorsBeforeInitialization
postProcessBeanFactory
BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
applyPropertyValues
registerBeanPostProcessors
BeanFactoryPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
BeanPostProcessor.postProcessBeforeInitialization
给【单例对象 及 被Scope管辖的实例】注册销毁方法DisposableBeanAdapter
默认支持提前引用allowEarlyReference = true
DefaultSingletonBeanRegistry.getSingleton(String beanName)
BeanPostProcessor.postProcessAfterInitialization
FactoryBeanRegistrySupport.doGetObjectFromFactoryBean
修改bean实例的属性值。1、AutowiredAnnotationBeanPostProcessor在这处理@Autowired、@Value2、CommonAnnotationBeanPostProcessor在这处理@Resource
autowireByName | autowireByType
InitializingBean.afterPropertiesSet 优先于 InitMethod(eg. @Bean指定的initMethod)
返回一个proxy_bean,有机会在Instantiation阶段前替换target_bean
返回创建的target_bean
FactoryBean获取真实Bean实例
applyBeanPostProcessorsAfterInitialization: BeanPostProcessor.postProcessAfterInitialization
applyBeanPostProcessorsBeforeInstantiation: InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
判定:bean实例不为空
判定:是否等于创建的target_bean
最后对bean进行属性修改。最重要的是执行:AnnotationAwareAspectJAutoProxyCreator的超类方法AbstractAutoProxyCreator.wrapIfNecessary:判定是有匹配Pointcut规则的Advisor则创建代理proxy_bean
容器启动AbstractApplicationContext.refresh()
前者用于构造函数注入,后者使用默认的构造函数
只执行BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口方法; 对于其他的Aware在下面再处理。
只适用于单例模式:按优先级从三级缓存中获取指定名称的对象: singletonObjects > earlySingletonObjects -> singletonFactories。 若存在于第三级缓存singletonFactories,则拿出来执行ObjectFactory.getObject(),并从第三级缓存中删除;执行结果放入第二级缓存earlySingletonObjects中。 这个结果可能是target_bean,也可能是判定需要生成代理时创建的proxy_bean.判定代理过程:AnnotationAwareAspectJAutoProxyCreator(AbstractAutoProxyCreator).wrapIfNecessary判定是有匹配Pointcut规则的Advisor。ps:这样主要是为了统一设计:正常流程是在bean创建过程的最后来判定是否创建代理,所以需要有一个懒处理。
registerListeners
真正创建bean实例的过程: 实例化 Instantiation -> 赋值populateBean -> 初始化initializeBean
返回创建的对象
FactoryBeanRegistrySupport.getObjectFromFactoryBean
返回true/false来控制是否继续Population过程。通常都返回ture标识继续执行
prepareBeanFactory
obtainFreshBeanFactory
invokeBeanFactoryPostProcessors
1、 自定义的启动类BootstrapApplication在SpringApplication.run启动过程里【prepareContext -> load】 阶段被创建了BeanDefinition到容器中。2 、BasePackages 由 @AutoConfigurationPackage上@Import的AutoConfigurationPackages#Registrar构建,通常是启动类的包路径。3、 声明ClassPathBeanDefinitionScanner进行扫描: 1、ImportBeanDefinitionRegistrar接口方法的实现。 2、 BeanDefinitionRegistryPostProcessor接口方法的实现。
下图主要讲述ObjectFactory.getObject()过程: AbstractAutowireCapableBeanFactory.createBean除Prototype 模式(直接执行创建)外,Singleton | Scope 都会以ObjectFactory来封装该创建bean对象的方法。
unsatisfiedNonSimpleProperties
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
applyBeanPostProcessorsAfterInitialization
Instantiation
java内省机制通过Setter方式确定Bean需注入的属性值对
最重要
更新并获取BeanFactory对象,springBoot下通常是DefaultListableBeanFactory。eg. 这里触发执行AnnotationConfigWebApplicationContext.loadBeanDefinitions来扫描指定路径下包里的类
判定:单例模式
对bean进行属性修改。也包括ApplicationContextAwareProcessor处理一些Aware接口
initApplicationEventMulticaster
autowireConstructor | instantiateBean
排序的优先级:PriorityOrdered > Ordered > 无
applyMergedBeanDefinitionPostProcessors
收藏
0 条评论
回复 删除
下一页