SpringBoot源码之Bean的生命周期是什么

其他教程   发布日期:2025年02月14日   浏览次数:241

本文小编为大家详细介绍“SpringBoot源码之Bean的生命周期是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringBoot源码之Bean的生命周期是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

入口方法为SpringApplication#run()

1.

  1. SpringApplication#run()
  1. /**
  2. * Run the Spring application, creating and refreshing a new
  3. * {@link ApplicationContext}.
  4. * @param args the application arguments (usually passed from a Java main method)
  5. * @return a running {@link ApplicationContext}
  6. */
  7. public ConfigurableApplicationContext run(String... args) {
  8. long startTime = System.nanoTime();
  9. DefaultBootstrapContext bootstrapContext = createBootstrapContext();
  10. ConfigurableApplicationContext context = null;
  11. configureHeadlessProperty();
  12. SpringApplicationRunListeners listeners = getRunListeners(args);
  13. listeners.starting(bootstrapContext, this.mainApplicationClass);
  14. try {
  15. ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
  16. ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
  17. Banner printedBanner = printBanner(environment);
  18. context = createApplicationContext();
  19. context.setApplicationStartup(this.applicationStartup);
  20. prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
  21. refreshContext(context);
  22. afterRefresh(context, applicationArguments);
  23. Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
  24. if (this.logStartupInfo) {
  25. new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
  26. }
  27. listeners.started(context, timeTakenToStartup);
  28. callRunners(context, applicationArguments);
  29. }
  30. catch (Throwable ex) {
  31. if (ex instanceof AbandonedRunException) {
  32. throw ex;
  33. }
  34. handleRunFailure(context, ex, listeners);
  35. throw new IllegalStateException(ex);
  36. }
  37. try {
  38. if (context.isRunning()) {
  39. Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
  40. listeners.ready(context, timeTakenToReady);
  41. }
  42. }
  43. catch (Throwable ex) {
  44. if (ex instanceof AbandonedRunException) {
  45. throw ex;
  46. }
  47. handleRunFailure(context, ex, null);
  48. throw new IllegalStateException(ex);
  49. }
  50. return context;
  51. }

2.

  1. SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()
  1. @Override
  2. public void refresh() throws BeansException, IllegalStateException {
  3. synchronized (this.startupShutdownMonitor) {
  4. StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
  5. // Prepare this context for refreshing.
  6. prepareRefresh();
  7. // Tell the subclass to refresh the internal bean factory.
  8. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  9. // Prepare the bean factory for use in this context.
  10. prepareBeanFactory(beanFactory);
  11. try {
  12. // Allows post-processing of the bean factory in context subclasses.
  13. postProcessBeanFactory(beanFactory);
  14. StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
  15. // Invoke factory processors registered as beans in the context.
  16. invokeBeanFactoryPostProcessors(beanFactory);
  17. // Register bean processors that intercept bean creation.
  18. registerBeanPostProcessors(beanFactory);
  19. beanPostProcess.end();
  20. // Initialize message source for this context.
  21. initMessageSource();
  22. // Initialize event multicaster for this context.
  23. initApplicationEventMulticaster();
  24. // Initialize other special beans in specific context subclasses.
  25. onRefresh();
  26. // Check for listener beans and register them.
  27. registerListeners();
  28. // Instantiate all remaining (non-lazy-init) singletons.
  29. finishBeanFactoryInitialization(beanFactory);
  30. // Last step: publish corresponding event.
  31. finishRefresh();
  32. }
  33. catch (BeansException ex) {
  34. if (logger.isWarnEnabled()) {
  35. logger.warn("Exception encountered during context initialization - " +
  36. "cancelling refresh attempt: " + ex);
  37. }
  38. // Destroy already created singletons to avoid dangling resources.
  39. destroyBeans();
  40. // Reset 'active' flag.
  41. cancelRefresh(ex);
  42. // Propagate exception to caller.
  43. throw ex;
  44. }
  45. finally {
  46. // Reset common introspection caches in Spring's core, since we
  47. // might not ever need metadata for singleton beans anymore...
  48. resetCommonCaches();
  49. contextRefresh.end();
  50. }
  51. }
  52. }

3.

  1. SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()
  1. @Override
  2. public void preInstantiateSingletons() throws BeansException {
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Pre-instantiating singletons in " + this);
  5. }
  6. // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  7. // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  8. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
  9. // Trigger initialization of all non-lazy singleton beans...
  10. for (String beanName : beanNames) {
  11. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  12. if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  13. if (isFactoryBean(beanName)) {
  14. Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  15. if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
  16. getBean(beanName);
  17. }
  18. }
  19. else {
  20. // 此处就是初始化bean的方法
  21. getBean(beanName);
  22. }
  23. }
  24. }
  25. // Trigger post-initialization callback for all applicable beans...
  26. for (String beanName : beanNames) {
  27. // 此处就是解决循环依赖的代码
  28. Object singletonInstance = getSingleton(beanName);
  29. if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
  30. StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
  31. .tag("beanName", beanName);
  32. smartSingleton.afterSingletonsInstantiated();
  33. smartInitialize.end();
  34. }
  35. }
  36. }

解决循环依赖的代码如下:

  1. protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  2. // 尝试从缓存中获取成品的目标对象,如果存在,则直接返回
  3. Object singletonObject = this.singletonObjects.get(beanName);
  4. // 如果缓存中不存在目标对象,则判断当前对象是否已经处于创建过程中,在前面的讲解中,第一次尝试获取A对象
  5. // 的实例之后,就会将A对象标记为正在创建中,因而最后再尝试获取A对象的时候,这里的if判断就会为true
  6. if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
  7. synchronized (this.singletonObjects) {
  8. singletonObject = this.earlySingletonObjects.get(beanName);
  9. if (singletonObject == null && allowEarlyReference) {
  10. // 这里的singletonFactories是一个Map,其key是bean的名称,而值是一个ObjectFactory类型的
  11. // 对象,这里对于A和B而言,调用图其getObject()方法返回的就是A和B对象的实例,无论是否是半成品
  12. ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
  13. if (singletonFactory != null) {
  14. // 获取目标对象的实例
  15. singletonObject = singletonFactory.getObject();
  16. this.earlySingletonObjects.put(beanName, singletonObject);
  17. this.singletonFactories.remove(beanName);
  18. }
  19. }
  20. }
  21. }
  22. return singletonObject;
  23. }
  • 一级缓存,singletonObjects 单例缓存,存储已经实例化的单例bean。

  • 二级缓存,earlySingletonObjects 提前暴露的单例缓存,这里存储的bean是刚刚构造完成,但还会通过属性注入bean。

  • 三级缓存,singletonFactories 生产单例的工厂缓存,存储工厂。

解决原理如下:

  • 在第一层中,先去获取 A 的 Bean,发现没有就准备去创建一个,然后将 A 的代理工厂放入“三级缓存”(这个 A 其实是一个半成品,还没有对里面的属性进行注入),但是 A 依赖 B 的创建,就必须先去创建 B;

  • 在第二层中,准备创建 B,发现 B 又依赖 A,需要先去创建 A,去创建 A,因为第一层已经创建了 A 的代理工厂,直接从“三级缓存”中拿到 A 的代理工厂,获取 A 的代理对象,放入“二级缓存”,并清除“三级缓存”;

  • 有了 A 的代理对象,对 A 的依赖完美解决(这里的 A 仍然是个半成品),B 初始化成功。在 B 初始化成功,完成 A 对象的属性注入,然后再填充 A 的其它属性,以及 A 的其它步骤(包括 AOP),完成对 A 完整的初始化功能(这里的 A 才是完整的 Bean)。

  • 将 A 放入“一级缓存”。

4.

  1. SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()=>AbstractBeanFactory#getBean() => AbstractBeanFactory#doGetBean()=>AbstractBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#doCreateBean()

bean的生命周期:

1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation
跟进doCreateBean()

  1. @Override
  2. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  3. throws BeanCreationException {
  4. if (logger.isTraceEnabled()) {
  5. logger.trace("Creating instance of bean '" + beanName + "'");
  6. }
  7. RootBeanDefinition mbdToUse = mbd;
  8. // Make sure bean class is actually resolved at this point, and
  9. // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  10. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  11. mbdToUse = new RootBeanDefinition(mbd);
  12. mbdToUse.setBeanClass(resolvedClass);
  13. }
  14. // Prepare method overrides.
  15. try {
  16. mbdToUse.prepareMethodOverrides();
  17. }
  18. catch (BeanDefinitionValidationException ex) {
  19. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  20. beanName, "Validation of method overrides failed", ex);
  21. }
  22. try {
  23. // 1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation
  24. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  25. if (bean != null) {
  26. return bean;
  27. }
  28. }
  29. catch (Throwable ex) {
  30. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  31. "BeanPostProcessor before instantiation of bean failed", ex);
  32. }
  33. try {
  34. // 跟进doCreateBean()
  35. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  36. if (logger.isTraceEnabled()) {
  37. logger.trace("Finished creating instance of bean '" + beanName + "'");
  38. }
  39. return beanInstance;
  40. }
  41. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  42. // A previously detected exception with proper bean creation context already,
  43. // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex;
  44. }
  45. catch (Throwable ex) {
  46. throw new BeanCreationException(
  47. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  48. }
  49. }

2.创建bean实例

跟进populateBean()
跟进initializeBean()

  1. protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  2. throws BeanCreationException {
  3. // Instantiate the bean.
  4. BeanWrapper instanceWrapper = null;
  5. if (mbd.isSingleton()) {
  6. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  7. }
  8. if (instanceWrapper == null) {
  9. // 2.创建bean实例
  10. instanceWrapper = createBeanInstance(beanName, mbd, args);
  11. }
  12. Object bean = instanceWrapper.getWrappedInstance();
  13. Class<?> beanType = instanceWrapper.getWrappedClass();
  14. if (beanType != NullBean.class) {
  15. mbd.resolvedTargetType = beanType;
  16. }
  17. // Allow post-processors to modify the merged bean definition.
  18. synchronized (mbd.postProcessingLock) {
  19. if (!mbd.postProcessed) {
  20. try {
  21. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  22. }
  23. catch (Throwable ex) {
  24. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  25. "Post-processing of merged bean definition failed", ex);
  26. }
  27. mbd.markAsPostProcessed();
  28. }
  29. }
  30. // Eagerly cache singletons to be able to resolve circular references
  31. // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  32. isSingletonCurrentlyInCreation(beanName));
  33. if (earlySingletonExposure) {
  34. if (logger.isTraceEnabled()) {
  35. logger.trace("Eagerly caching bean '" + beanName +
  36. "' to allow for resolving potential circular references");
  37. }
  38. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  39. }
  40. // Initialize the bean instance.
  41. Object exposedObject = bean;
  42. try {
  43. // 跟进populateBean()
  44. populateBean(beanName, mbd, instanceWrapper);
  45. // 跟进initializeBean()
  46. exposedObject = initializeBean(beanName, exposedObject, mbd);
  47. }
  48. catch (Throwable ex) {
  49. if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {
  50. throw bce;
  51. }
  52. else {
  53. throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
  54. }
  55. }
  56. if (earlySingletonExposure) {
  57. Object earlySingletonReference = getSingleton(beanName, false);
  58. if (earlySingletonReference != null) {
  59. if (exposedObject == bean) {
  60. exposedObject = earlySingletonReference;
  61. }
  62. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  63. String[] dependentBeans = getDependentBeans(beanName);
  64. Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
  65. for (String dependentBean : dependentBeans) {
  66. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  67. actualDependentBeans.add(dependentBean);
  68. }
  69. }
  70. if (!actualDependentBeans.isEmpty()) {
  71. throw new BeanCurrentlyInCreationException(beanName,
  72. "Bean with name '" + beanName + "' has been injected into other beans [" +
  73. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  74. "] in its raw version as part of a circular reference, but has eventually been " +
  75. "wrapped. This means that said other beans do not use the final version of the " +
  76. "bean. This is often the result of over-eager type matching - consider using " +
  77. "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
  78. }
  79. }
  80. }
  81. }
  82. // Register bean as disposable.
  83. try {
  84. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  85. }
  86. catch (BeanDefinitionValidationException ex) {
  87. throw new BeanCreationException(
  88. mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  89. }
  90. return exposedObject;
  91. }

3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation

4.注入bean属性

  1. protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  2. if (bw == null) {
  3. if (mbd.hasPropertyValues()) {
  4. throw new BeanCreationException(
  5. mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
  6. }
  7. else {
  8. // Skip property population phase for null instance.
  9. return;
  10. }
  11. }
  12. if (bw.getWrappedClass().isRecord()) {
  13. if (mbd.hasPropertyValues()) {
  14. throw new BeanCreationException(
  15. mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");
  16. }
  17. else {
  18. // Skip property population phase for records since they are immutable.
  19. return;
  20. }
  21. }
  22. // 3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation
  23. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  24. if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  25. return;
  26. }
  27. }
  28. }
  29. PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
  30. int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  31. if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  32. MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
  33. // Add property values based on autowire by name if applicable.
  34. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
  35. autowireByName(beanName, mbd, bw, newPvs);
  36. }
  37. // Add property values based on autowire by type if applicable.
  38. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  39. autowireByType(beanName, mbd, bw, newPvs);
  40. }
  41. pvs = newPvs;
  42. }
  43. if (hasInstantiationAwareBeanPostProcessors()) {
  44. if (pvs == null) {
  45. pvs = mbd.getPropertyValues();
  46. }
  47. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  48. PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
  49. if (pvsToUse == null) {
  50. return;
  51. }
  52. pvs = pvsToUse;
  53. }
  54. }
  55. boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
  56. if (needsDepCheck) {
  57. PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  58. checkDependencies(beanName, mbd, filteredPds, pvs);
  59. }
  60. if (pvs != null) {
  61. // 4.注入属性
  62. applyPropertyValues(beanName, mbd, bw, pvs);
  63. }
  64. }

5.设置Aware接口的属性

6.调用BeanPostProcessor的初始化前置方法

7.先((InitializingBean) bean).afterPropertiesSet(),后调用init-method方法,进行初始化操作

8.调用BeanPostProcessor的初始化后置方法

  1. protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
  2. // 5.设置Aware接口的属性
  3. invokeAwareMethods(beanName, bean);
  4. Object wrappedBean = bean;
  5. if (mbd == null || !mbd.isSynthetic()) {
  6. // 5.调用BeanPostProcessor的初始化前置方法
  7. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  8. }
  9. try {
  10. // 6.调用init-method方法,进行初始化操作
  11. invokeInitMethods(beanName, wrappedBean, mbd);
  12. }
  13. catch (Throwable ex) {
  14. throw new BeanCreationException(
  15. (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
  16. }
  17. if (mbd == null || !mbd.isSynthetic()) {
  18. // 7. 调用BeanPostProcessor的初始化后置方法
  19. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  20. }
  21. return wrappedBean;
  22. }

以上就是SpringBoot源码之Bean的生命周期是什么的详细内容,更多关于SpringBoot源码之Bean的生命周期是什么的资料请关注九品源码其它相关文章!