阅读对象:适合想自己跟源码代码的同学,下面是Bean生命周期的关键代码,可以可在下面代码打debug,快速定位到生命周期的关键代码。
(ps:图是盗用的,如有违权请联系作者,会立即删除,tks)
BeanDefinitio加载逻辑:
主要源码入口是在:AbstractApplicationContext中invokeBeanFactoryPostProcessors方法继续更进这个方法然后会进入到PostProcessorRegistrationDelegate 的invokeBeanDefinitionRegistryPostProcessors方法如下
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
.tag("postProcessor", postProcessor::toString);
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();
}
}
嘿嘿:所以代码重点就是BeanDefinitionRegistryPostProcessor接口的postProcessorBeanDefinitionRegistry方法实现啦(作者的能力有限,里面的代码细节作者目前也只是大概看了一下,后面再仔细研究)
Bean的实例化:
源码入口: 1.AbstractApplicationContext.registerBeanPostProcessors(beanFactory)--》 PostProcessorRegistrationDelegate.registerBeanPostProcessors: 主要实例化实现了BeanPostProcessor接口的Bean,也就是注册BeanPostProcessor,查看bean的实例化过程找到AbstractBeanFactory.getBean然后进入doGetBean->createBean
2.AbstractApplicationContext中finishBeanFactoryInitialization(beanFactory):初始化剩余未实列化的bean中间方法省略直接,进入到getBean然后进入到AbatractAutowaireCapabaleBeanFactory.createBean方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
mbdToUse.prepareMethodOverrides();
**// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.**
//创建实例前首先会去调用BeanPostProcessor接口方法,返回一个Bean,如果不为空就不用去调用doCreateBean方法实例化对象了。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
上面的关键代码resolveBeforeInstantiation调用InstantiationAwareBeanPostProcessor接口的 postProcessBeforeInstantiation、postProcessAfterInitialization,beafor方法可返回一个自定义创建的bean,跳过spring反射去创建Bean。spring反射创建就要进入到doCreateBean方法中去看了
问题:什么场景回去实现BeanPostProcessor接口去自定义实例化对象呢
属性赋值 关键代码:AbstractAutowaireCapabaleBeanFactory.doCreateBean-> populateBean(beanName, mbd, instanceWrapper);
//利用反射调用构造器创建实例得到一个bean(这块代码省略)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//属性赋值的代码就在这里了
populateBean(beanName, mbd, instanceWrapper);
//下面的初始化就是这个方法啦
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
bean的初始化 关键代码:AbstractAutowaireCapabaleBeanFactory.doCreateBean-> initializeBean(beanName, mbd, instanceWrapper);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//初始化前的动作,调用BeanPostProcessor的Befor接口
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
if (mbd == null || !mbd.isSynthetic()) {
//初始化后的操作
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
注意:初始化方法如果调用了循环依赖的bean,回发生什么问题呢?比如A依赖B,B依赖A,先加载A,然后populateBean会去实例化B,然后执行initMethods的时候这个方法又去调用了未完成初始化的A的方法,此时就有可能出现问题。。。。。。
Bean销毁 会调用DisposableBean方法,源码就不贴了。