首頁 > Java > java教程 > SpringBoot源碼之Bean的生命週期是什麼

SpringBoot源碼之Bean的生命週期是什麼

王林
發布: 2023-05-11 12:43:12
轉載
1563 人瀏覽過

入口方法為SpringApplication#run()

1.SpringApplication#run()

/**
	 * Run the Spring application, creating and refreshing a new
	 * {@link ApplicationContext}.
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return a running {@link ApplicationContext}
	 */
	public ConfigurableApplicationContext run(String... args) {
		long startTime = System.nanoTime();
		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
		ConfigurableApplicationContext context = null;
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			context.setApplicationStartup(this.applicationStartup);
			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
			}
			listeners.started(context, timeTakenToStartup);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			if (ex instanceof AbandonedRunException) {
				throw ex;
			}
			handleRunFailure(context, ex, listeners);
			throw new IllegalStateException(ex);
		}
		try {
			if (context.isRunning()) {
				Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
				listeners.ready(context, timeTakenToReady);
			}
		}
		catch (Throwable ex) {
			if (ex instanceof AbandonedRunException) {
				throw ex;
			}
			handleRunFailure(context, ex, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}
登入後複製

2.SpringApplication# run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()##rr

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}
登入後複製
##SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=&Factorbation)=Application; >ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()

@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
						getBean(beanName);
					}
				}
				else {
					// 此处就是初始化bean的方法
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			// 此处就是解决循环依赖的代码
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				smartSingleton.afterSingletonsInstantiated();
				smartInitialize.end();
			}
		}
	}
登入後複製
解決循環依賴的程式碼如下:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 尝试从缓存中获取成品的目标对象,如果存在,则直接返回
  Object singletonObject = this.singletonObjects.get(beanName);
  // 如果缓存中不存在目标对象,则判断当前对象是否已经处于创建过程中,在前面的讲解中,第一次尝试获取A对象
  // 的实例之后,就会将A对象标记为正在创建中,因而最后再尝试获取A对象的时候,这里的if判断就会为true
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    synchronized (this.singletonObjects) {
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
        // 这里的singletonFactories是一个Map,其key是bean的名称,而值是一个ObjectFactory类型的
        // 对象,这里对于A和B而言,调用图其getObject()方法返回的就是A和B对象的实例,无论是否是半成品
        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
        if (singletonFactory != null) {
          // 获取目标对象的实例
          singletonObject = singletonFactory.getObject();
          this.earlySingletonObjects.put(beanName, singletonObject);
          this.singletonFactories.remove(beanName);
        }
      }
    }
  }
  return singletonObject;
}
登入後複製

@Override  
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)  
      throws BeanCreationException {  
  
   if (logger.isTraceEnabled()) {  
      logger.trace("Creating instance of bean &#39;" + beanName + "&#39;");  
   }  
   RootBeanDefinition mbdToUse = mbd;  
  
   // Make sure bean class is actually resolved at this point, and  
   // 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);  
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {  
      mbdToUse = new RootBeanDefinition(mbd);  
      mbdToUse.setBeanClass(resolvedClass);  
   }  
  
   // Prepare method overrides.  
   try {  
      mbdToUse.prepareMethodOverrides();  
   }  
   catch (BeanDefinitionValidationException ex) {  
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),  
            beanName, "Validation of method overrides failed", ex);  
   }  
  
   try {  
      // 1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);  
      if (bean != null) {  
         return bean;  
      }  
   }  
   catch (Throwable ex) {  
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,  
            "BeanPostProcessor before instantiation of bean failed", ex);  
   }  
  
   try {  
	  // 跟进doCreateBean()
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);  
      if (logger.isTraceEnabled()) {  
         logger.trace("Finished creating instance of bean &#39;" + beanName + "&#39;");  
      }  
      return beanInstance;  
   }  
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {  
      // A previously detected exception with proper bean creation context already,  
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.      throw ex;  
   }  
   catch (Throwable ex) {  
      throw new BeanCreationException(  
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);  
   }  
}
登入後複製

解決循環依賴的程式碼如下:
    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)  
          throws BeanCreationException {  
      
       // Instantiate the bean.  
       BeanWrapper instanceWrapper = null;  
       if (mbd.isSingleton()) {  
          instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
       }  
       if (instanceWrapper == null) { 
    	  // 2.创建bean实例 
          instanceWrapper = createBeanInstance(beanName, mbd, args);  
       }  
       Object bean = instanceWrapper.getWrappedInstance();  
       Class<?> beanType = instanceWrapper.getWrappedClass();  
       if (beanType != NullBean.class) {  
          mbd.resolvedTargetType = beanType;  
       }  
      
       // Allow post-processors to modify the merged bean definition.  
       synchronized (mbd.postProcessingLock) {  
          if (!mbd.postProcessed) {  
             try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);  
             }  
             catch (Throwable ex) {  
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,  
                      "Post-processing of merged bean definition failed", ex);  
             }  
             mbd.markAsPostProcessed();  
          }  
       }  
      
       // Eagerly cache singletons to be able to resolve circular references  
       // even when triggered by lifecycle interfaces like BeanFactoryAware.   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&  
             isSingletonCurrentlyInCreation(beanName));  
       if (earlySingletonExposure) {  
          if (logger.isTraceEnabled()) {  
             logger.trace("Eagerly caching bean &#39;" + beanName +  
                   "&#39; to allow for resolving potential circular references");  
          }  
          addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  
       }  
      
       // Initialize the bean instance.  
       Object exposedObject = bean;  
       try {
    	  // 跟进populateBean()
          populateBean(beanName, mbd, instanceWrapper); 
          // 跟进initializeBean() 
          exposedObject = initializeBean(beanName, exposedObject, mbd);  
       }  
       catch (Throwable ex) {  
          if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {  
             throw bce;  
          }  
          else {  
             throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);  
          }  
       }  
      
       if (earlySingletonExposure) {  
          Object earlySingletonReference = getSingleton(beanName, false);  
          if (earlySingletonReference != null) {  
             if (exposedObject == bean) {  
                exposedObject = earlySingletonReference;  
             }  
             else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {  
                String[] dependentBeans = getDependentBeans(beanName);  
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);  
                for (String dependentBean : dependentBeans) {  
                   if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {  
                      actualDependentBeans.add(dependentBean);  
                   }  
                }  
                if (!actualDependentBeans.isEmpty()) {  
                   throw new BeanCurrentlyInCreationException(beanName,  
                         "Bean with name &#39;" + beanName + "&#39; has been injected into other beans [" +  
                         StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +  
                         "] in its raw version as part of a circular reference, but has eventually been " +  
                         "wrapped. This means that said other beans do not use the final version of the " +  
                         "bean. This is often the result of over-eager type matching - consider using " +  
                         "&#39;getBeanNamesForType&#39; with the &#39;allowEagerInit&#39; flag turned off, for example.");  
                }  
             }  
          }  
       }  
      
       // Register bean as disposable.  
       try {  
          registerDisposableBeanIfNecessary(beanName, bean, mbd);  
       }  
       catch (BeanDefinitionValidationException ex) {  
          throw new BeanCreationException(  
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);  
       }  
      
       return exposedObject;  
    }
    登入後複製
  • protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {  
       if (bw == null) {  
          if (mbd.hasPropertyValues()) {  
             throw new BeanCreationException(  
                   mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");  
          }  
          else {  
             // Skip property population phase for null instance.  
             return;  
          }  
       }  
      
       if (bw.getWrappedClass().isRecord()) {  
          if (mbd.hasPropertyValues()) {  
             throw new BeanCreationException(  
                   mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");  
          }  
          else {  
             // Skip property population phase for records since they are immutable.  
             return;  
          }  
       }  
      
          // 3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation
          for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {  
             if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {  
                return;  
             }  
          }  
       }  
      
       PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);  
      
       int resolvedAutowireMode = mbd.getResolvedAutowireMode();  
       if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {  
          MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
          // Add property values based on autowire by name if applicable.  
          if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {  
             autowireByName(beanName, mbd, bw, newPvs);  
          }  
          // Add property values based on autowire by type if applicable.  
          if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {  
             autowireByType(beanName, mbd, bw, newPvs);  
          }  
          pvs = newPvs;  
       }  
       if (hasInstantiationAwareBeanPostProcessors()) {  
          if (pvs == null) { 
             pvs = mbd.getPropertyValues();  
          }  
          for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {  
             PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);  
             if (pvsToUse == null) {  
                return;  
             }  
             pvs = pvsToUse;  
          }  
       }  
      
       boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);  
       if (needsDepCheck) {  
          PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  
          checkDependencies(beanName, mbd, filteredPds, pvs);  
       }  
      
       if (pvs != null) {
    	  // 4.注入属性  
          applyPropertyValues(beanName, mbd, bw, pvs);  
       }  
    }
    登入後複製
    #sing#leton#單例緩存,儲存已經實例化的單例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.

SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=> ;AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstFactorFactorSingletons()=>DefaultListableBeanFactory#preInstFactorFactorSingletons()=>DefaultListableBeanFactory#preInstFactorFactorSingletons()=>DefaultListableBeanFactory#InstFactorFactorSingleton(Instantiate); Bean()=>AbstractBeanFactory #createBean()=>AbstractAutowireCapableBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#doCreateBean()

bean的生命週期:

orest#1.Instantiation#1.Instantiation#Post:

core#1.Instantiation#1.Instantiation#Postost進doCreateBean()

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 5.设置Aware接口的属性
   invokeAwareMethods(beanName, bean);  
  
   Object wrappedBean = bean;  
   if (mbd == null || !mbd.isSynthetic()) {
	  // 5.调用BeanPostProcessor的初始化前置方法  
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);  
   }  
  
   try {
	  // 6.调用init-method方法,进行初始化操作  
      invokeInitMethods(beanName, wrappedBean, mbd);  
   }  
   catch (Throwable ex) {  
      throw new BeanCreationException(  
            (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);  
   }  
   if (mbd == null || !mbd.isSynthetic()) { 
      // 7. 调用BeanPostProcessor的初始化后置方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);  
   }  
  
   return wrappedBean;  
}
登入後複製

2.建立bean實例

跟進populateBean()

跟進initializeBean()

rrreee
3.呼叫InstantiationAwareBeanPostProcessor#ation#ProcessAfterInstantiation##Process

#4.注入bean屬性

rrreee

5.設定Aware介面的屬性

6.呼叫BeanPostProcessor的初始化前置方法

7.先((InitializingBean ) bean).afterPropertiesSet(),後來呼叫init-method方法,進行初始化操作

8.呼叫BeanPostProcessor的初始化後置方法

rrreee

以上是SpringBoot源碼之Bean的生命週期是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板