SpringBoot源碼之Bean的生命周期
入口方法為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()
@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(); } } }
3.SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>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) { // 此處就是解決循環(huán)依賴的代碼 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(); } } }
解決循環(huán)依賴的代碼如下:
protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 嘗試從緩存中獲取成品的目標(biāo)對(duì)象,如果存在,則直接返回 Object singletonObject = this.singletonObjects.get(beanName); // 如果緩存中不存在目標(biāo)對(duì)象,則判斷當(dāng)前對(duì)象是否已經(jīng)處于創(chuàng)建過程中,在前面的講解中,第一次嘗試獲取A對(duì)象 // 的實(shí)例之后,就會(huì)將A對(duì)象標(biāo)記為正在創(chuàng)建中,因而最后再嘗試獲取A對(duì)象的時(shí)候,這里的if判斷就會(huì)為true if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 這里的singletonFactories是一個(gè)Map,其key是bean的名稱,而值是一個(gè)ObjectFactory類型的 // 對(duì)象,這里對(duì)于A和B而言,調(diào)用圖其getObject()方法返回的就是A和B對(duì)象的實(shí)例,無論是否是半成品 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 獲取目標(biāo)對(duì)象的實(shí)例 singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
- 一級(jí)緩存,singletonObjects 單例緩存,存儲(chǔ)已經(jīng)實(shí)例化的單例bean。
- 二級(jí)緩存,earlySingletonObjects 提前暴露的單例緩存,這里存儲(chǔ)的bean是剛剛構(gòu)造完成,但還會(huì)通過屬性注入bean。
- 三級(jí)緩存,singletonFactories 生產(chǎn)單例的工廠緩存,存儲(chǔ)工廠。
解決原理如下:
- 在第一層中,先去獲取 A 的 Bean,發(fā)現(xiàn)沒有就準(zhǔn)備去創(chuàng)建一個(gè),然后將 A 的代理工廠放入“三級(jí)緩存”(這個(gè) A 其實(shí)是一個(gè)半成品,還沒有對(duì)里面的屬性進(jìn)行注入),但是 A 依賴 B 的創(chuàng)建,就必須先去創(chuàng)建 B;
- 在第二層中,準(zhǔn)備創(chuàng)建 B,發(fā)現(xiàn) B 又依賴 A,需要先去創(chuàng)建 A,去創(chuàng)建 A,因?yàn)榈谝粚右呀?jīng)創(chuàng)建了 A 的代理工廠,直接從“三級(jí)緩存”中拿到 A 的代理工廠,獲取 A 的代理對(duì)象,放入“二級(jí)緩存”,并清除“三級(jí)緩存”;
- 有了 A 的代理對(duì)象,對(duì) A 的依賴完美解決(這里的 A 仍然是個(gè)半成品),B 初始化成功。在 B 初始化成功,完成 A 對(duì)象的屬性注入,然后再填充 A 的其它屬性,以及 A 的其它步驟(包括 AOP),完成對(duì) A 完整的初始化功能(這里的 A 才是完整的 Bean)。
- 將 A 放入“一級(jí)緩存”。
4.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.調(diào)用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation
跟進(jìn)doCreateBean()
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } 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.調(diào)用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 { // 跟進(jìn)doCreateBean() Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } 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); } }
2.創(chuàng)建bean實(shí)例
跟進(jìn)populateBean()
跟進(jìn)initializeBean()
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.創(chuàng)建bean實(shí)例 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 '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { // 跟進(jìn)populateBean() populateBean(beanName, mbd, instanceWrapper); // 跟進(jìn)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 '" + beanName + "' 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 " + "'getBeanNamesForType' with the 'allowEagerInit' 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; }
3.調(diào)用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation
4.注入bean屬性
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.調(diào)用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); } }
5.設(shè)置Aware接口的屬性
6.調(diào)用BeanPostProcessor的初始化前置方法
7.先((InitializingBean) bean).afterPropertiesSet(),后調(diào)用init-method方法,進(jìn)行初始化操作
8.調(diào)用BeanPostProcessor的初始化后置方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { // 5.設(shè)置Aware接口的屬性 invokeAwareMethods(beanName, bean); Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 5.調(diào)用BeanPostProcessor的初始化前置方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 6.調(diào)用init-method方法,進(jìn)行初始化操作 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. 調(diào)用BeanPostProcessor的初始化后置方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
以上就是SpringBoot源碼之Bean的生命周期的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Bean生命周期的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring中@RestControllerAdvice注解的使用詳解
這篇文章主要介紹了Spring中@RestControllerAdvice注解的使用詳解,@RestControllerAdvice是一個(gè)組合注解,由@ControllerAdvice、@ResponseBody組成,而@ControllerAdvice繼承了@Component,需要的朋友可以參考下2024-01-01Java調(diào)用第三方http接口的常用方式總結(jié)
這篇文章主要介紹了Java調(diào)用第三方http接口的常用方式總結(jié),具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06SpringCloud Bus消息總線的實(shí)現(xiàn)
消息總線是一種通信工具,可以在機(jī)器之間互相傳輸消息、文件等,這篇文章主要介紹了SpringCloud Bus消息總線的實(shí)現(xiàn),Spring cloud bus 通過輕量消息代理連接各個(gè)分布的節(jié)點(diǎn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05java實(shí)現(xiàn)簡單學(xué)生管理系統(tǒng)項(xiàng)目
這篇文章主要介紹了java實(shí)現(xiàn)簡單學(xué)生管理系統(tǒng)項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Java數(shù)組常用排序算法實(shí)例小結(jié)
這篇文章主要介紹了Java數(shù)組常用排序算法,結(jié)合實(shí)例形式總結(jié)分析了java數(shù)組常用的4種排序算法,包括冒泡排序、數(shù)組遞增排序、快速排序及選擇排序,需要的朋友可以參考下2017-12-12Java詳解實(shí)現(xiàn)多線程的四種方式總結(jié)
哈哈!經(jīng)過一個(gè)階段的學(xué)習(xí),Java基礎(chǔ)知識(shí)學(xué)習(xí)終于到多線程了!Java多線程以及后面互斥鎖的概念都是Java基礎(chǔ)學(xué)習(xí)的難點(diǎn),所以我做了一個(gè)總結(jié),希望對(duì)大家也有幫助2022-07-07springmvc項(xiàng)目使用@Valid+BindingResult遇到的問題
這篇文章主要介紹了springmvc項(xiàng)目使用@Valid+BindingResult遇到的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12