Spring Bean初始化流程
2022-03-23 17:18:34 3 举报
Spring Bean创建流程
作者其他创作
大纲/内容
创建bean的包装类
获取属性集合
根据属性名获取BeanWrapImpl对象,支持多重属性的递归分析处理
如果是新创建的bean,加入缓存并移除其他缓存,如果是其他方式创建的bean,说明已经加入过缓存,这里不用再加了
当当前 bean 实现了 BeanClassLoaderAware 接口,将 Spring 容器的 BeanClassLoader 注入到当前 bean
遍历属性,将属性转换为对应类的属性的类型
final Object bean = instanceWrapper.getWrappedInstance()
初始化bean流程
((BeanClassLoaderAware)bean).setBeanClassLoader(getBeanClassLoader())
return beanInstance
通过入参singletonFactory创建bean
获取BeanFactory:创建DefaultListableBeanFactory、加载BeanDefinition。
PropertyHandler ph = getLocalPropertyHandler(tokens.actualName)
final Class clazz = bd.getBeanClass()
refresh()
postProcessBeanFactory(beanFactory)
设置解析好的属性
子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
RuntimeBeanReference ref = (RuntimeBeanReference) value
bean instanceof BeanNameAware
1、Spring对Bean进行实例化;2、Spring将值和Bean的引用注入进Bean对应的属性中;3、注入Aware接口: 1)如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()方法; 2)如果Bean实现了BeanClassLoaderAware接口,Spring将把容器的BeanClassLoader注入到当前 bean; 3)如果Bean实现了BeanFactoryAware接口,Spring将把与bean初始化有关的BeanFactory(这里对应的是DefaultListableBeanFactory)实例注册给当前bean; 4)如果Bean实现了ApplicationContextAware接口,Spring将会把应用上下文注入到当前bean;4、如果Bean实现了BeanPostProcess接口,Spring将调用他们的postProcessBeforeInitialization()方法,在Bean实例创建成功后且实例化之前对其进行增强;5、如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法,作用与在配置文件中的Bean标签内使用init-method声明初始化的作用一样,在Bean的全部属性设置成功后执行;6、如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessAfterInitialization()方法,在Bean实例初始化成功后对其进行增强;7、之后Bean将一直驻留在应用上下文中给应用使用,直到应用上下文被销毁;8、如果Bean实现了Disposable接口,Spring将调用它的destory方法,作用与在配置文件中对Bean使用destory-method属性的作用一样,都是在Bean实例销毁前执行的方法。
获取bean实例
BeanWrapperImpl
获取bean,主要判断是获取FactoryBean还是获取FactoryBean的实例
TypedStringValue typedStringValue = (TypedStringValue) value
初始化bean的包装类
设置本地属性
创建单例bean
BeanUtil.instantiateClass(constructorToUse)
getBean(beanName)
prepareRefresh
当当前 bean 实现了 BeanNameAware 接口,调用 setBeanName
主要是为了把PropertyValues中的属性设置到bean中
return result
registerBeanPostProcessors(beanFactory)
ObjectFactory
创建BeanWrapper
从缓存中获取实例
if result == null return null
String refName = ref.getBeanName()
AbstractPropertyAccessor
DefaultListableBeanFactory
获取对应的的解析器
RuntimeBeanReference ref = (RuntimeBeanReference) originalValue()
AbstracBeanFactory
获取合并bean定义RootBeanDefinition
AbstractNestablePropertyAccessor
AbstractNestableProperttyAccessor nestedPa = getPropertyAccessorForPropertyPath(propertyName)
finishBeanFactoryInitialization(beanFactory)
填充属性
进行初始化以及设置被包装的对象
((BeanName)bean).setBeanName(beanName)
Method
生成PropertyTokenHolder,内省设置属性值
initBeanWrapper(bw)
注册应用的监听器
originValue instanceof RuntimeBeanReference
属性访问器
判断是否需要提前曝光(解决循环依赖),即在bean初始化完成前将创建实例的ObjectFactory加入工厂
创建后检查,移除加载状态
onRefresh()
finishRefresh()
invokeBeanFactoryPostProcessors(beanFactory)
刷新完成工作,包括初始化LifecycleProcessor,发布刷新完成事件等
BeanDefinitionValueResolver
ClassPathXmlApplicationContext
初始化国际化语言的支持
将BeanFactory中的ConversionService(类型转换器)添加到bean的包装类中
more
bean instanceof BeanClassLoaderAware
Object originValue = pv.getValue()
当当前bean实现了BeanFactoryAware接口,Spring将把与bean初始化有关的BeanFactory(这里对应的是DefaultListableBeanFactory)实例注册给当前bean
调用setterMethod的invoke方法,通过反射,完成属性的注入
设置WriteMethod
setWrappedInstance
return (T)bean
调用 bean-post-processor 的 after initialization 回调方法
afterSingletonCreation(beanName)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
initMessageSource()
if(getCustomTypeConverter() == null)converter = bw;
开始创建bean,主要分为三步:1、实例化bean。2、bean的属性填充。3、初始化bean.
注册spring默认的属性编辑器
Spring中Bean的生命周期
((BeanFactoryAware)bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this)
Method writeMethod = ....... this.pd.getWriteMethod()
调用 bean-post-processor 的 before initialization 回调方法
String propertyName = pv.getName()
AbstractApplicationContext
getSingleton(beanName)
bean instanceof BeanFactoryAware
return evalute(typedStringValue())
initApplicationEventMulticaster()
setConversionService(getConversionService())
根据反射机制从BeanDefinitionRegistry找到所有实现了BeanFactoryPostProcessor接口的bean,并调用其postProcessorBeanFactory()方法
setPropertyValue(pv)
getMergedLocalBeanDefinition(beanName)
Object singletonObject = getObject()
用处理器把属性和方法上的自动装配信息记录下来,放到bean定义里面,后面填充的时候会用到
空方法,子类通过重写这个方法在BeanFactory创建并预准备之后做进一步的设置
BeanFactory预准备工作,如设置beanFactory的类加载器、添加后置处理器、设置忽略的自动装配接口、设置自动装配规则、注入一些其它信息的 bean。
注册用户自定义的属性编辑器
获取用户自定义的解析器
注册Bean的后置处理器
autowire自动注入,调用构造函数自动注入
List original = mpvs.getPropertyValueList()
初始化所有的单例bean(除懒加载)
这个接口继承了BeanPostProcessor,主要为了在bean实例化前后处理一些事情
有参数,又没有获取到构造方法,只能使用无参构造方法创建实例
originValue instanceof TypedStringValue
return bean
这里主要是对各种类型的属性解析,主要有bean的引用解析、beanName的引用解析、解析BeanDefinitionHolder(包含Bean name、aliases等)、解析BeanDefinition、解析List、解析Set、解析Map、解析Properties和解析带有目标类型的字符串。
SimpleInstantiationStrategy
AbstractAutowireCapableBeanFactory
quickStart
registerListeners()
Constructor constructorToUse = clazz.getDeclaredConstructor()
preInstantiateSingletons()
prepareBeanFactory(beanFactory)
loop
BeanWrapper bw = new BeanWrapperImpl(beanInstance)
直接使用反射实例化
使用FactoryBean的factory-bean来创建,支持静态工厂和实例工厂
return singletonObject
实例化预处理
InstantiationAwareBeanPostProcessor()
registerDefaultEditors()
刷新容器前的预处理:初始化一些属性、校验属性合法性、创建一个Set集合,保存容器中早期事件。
处理配置bean加了init-method 或 类上加了@PostConstruct的bean的回调
调用实现了Aware接口的方法,比如注入Application
registerCustomEditors(bw)
bw.setPropertyValues(new MutablePropertyValue(deepCopy))
初始化容器的事件广播器
Object bean = this.beanFactory.getParentBeanFactory().getBean(refName)
与上面before的逻辑类似
DefaultSingletonBeanRegistry
0 条评论
回复 删除
下一页