Bean生命周期源码跟踪

183 阅读2分钟

阅读对象:适合想自己跟源码代码的同学,下面是Bean生命周期的关键代码,可以可在下面代码打debug,快速定位到生命周期的关键代码。 image.png(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方法,源码就不贴了。