精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊一聊Spring Bean 的生命周期

開發 前端
什么情況下,這兩個 Bean 會不同呢?如果在 Bean 的后置處理器中,我們使用新的 Bean 替換了舊的 Bean,就會導致最終拿到的 exposedObject 和 bean 兩個變量指向的地址不再相同。如果不相同,就要檢查當前 Bean 是否有被容器中的其他 Bean 所依賴了,如果有,并且使用了當前 Bean 的 Bean 還正在創建中,那么就趕緊刪除掉重新創建,如果使用了當前 Bean

講一講 Spring Bean 的生命周期算是面試時候一道非常經典的問題了!

如果沒有研究過 Spring 源碼,單純去背面試題,這個問題也是可以回答出來的,但是單純的背缺乏理解,而且面試一緊張,就容易背岔了。但是如果你從頭到尾看了松哥的 Spring 源碼分析,那么這個問題就不需要背了,就根據自己對 Spring 源碼的理解講出來就行了。

在前面的文章中,松哥和大家分析了 Spring 中 Bean 的創建是在 createBean 方法中完成的,在該方法中,真正干活的實際上是 doCreateBean 方法,具體位置在 AbstractAutowireCapableBeanFactory#doCreateBean,小伙伴們在面試時候常被問到的 Spring Bean 的生命周期,實際上就是問 doCreateBean 方法的執行邏輯。

doCreateBean 方法整體上來說,干了四件事:

  1. Bean 的實例化。
  2. Bean 屬性填充。
  3. Bean 初始化。
  4. Bean 銷毀方法注冊。

這里大家注意區分實例化和初始化兩個方法,實例化是指通過反射創建出來 Bean 實例的過程,而初始化則是調用一些回調函數進行 bean 的一些預處理。

1. 實例化

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
 instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
 mbd.resolvedTargetType = beanType;
}

這段代碼的最終目的是為了獲取到一個 bean 實例。獲取之前先去檢查如果有該 bean 尚未完成的 factoryBean 實例就先移除掉。

createBeanInstance 方法就是大家閉著眼睛也能猜出來的通過反射創建 bean 實例過程,最后我們拿到的 bean 實例就是這個 bean。

實例化完成之后,還有兩個小細節。

一個是預留了后置處理器修改 BeanDefinition 的接口,在這里可以對 BeanDefinition 進行修改,這塊通常用來處理通過注解注入值的情況,這個松哥在之前的文章中也有詳細介紹過,小伙伴們參見:一個特殊的 BeanPostProcessor。

另外一個則是對于循環依賴的處理。

松哥之前的文章中已經和小伙伴們詳細分析了循環依賴的解決思路,參見:如何通過三級緩存解決 Spring 循環依賴。

這里要做的工作就是根據當前 Bean 的情況,將 Bean 存入到三級緩存中(二級緩存中不存):

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

這塊代碼的具體含義在之前的文章中松哥都和大家分析過了,這里就不再啰嗦了,感興趣的小伙伴戳這里:透過源碼,捋清楚循環依賴到底是如何解決的!。

2. 屬性填充

populateBean(beanName, mbd, instanceWrapper);

這一句就是屬性填充的環節了。屬性填充就是一個 Bean 中我們通過各種注解如 @Autowired 等注入的對象,@Value 注入的字符串,這些統一都在 populateBean 中進行處理。具體的代碼細節松哥在之前的文章中也和大家講過了:@Autowired 到底是怎么把變量注入進來的?。

3. 初始化

exposedObject = initializeBean(beanName, exposedObject, mbd);

初始化主要是干這樣四件事:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
 invokeAwareMethods(beanName, bean);
 Object wrappedBean = bean;
 if (mbd == null || !mbd.isSynthetic()) {
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 }
 try {
  invokeInitMethods(beanName, wrappedBean, mbd);
 }
 catch (Throwable ex) {
  throw new BeanCreationException(
    (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
 }
 if (mbd == null || !mbd.isSynthetic()) {
  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 }
 return wrappedBean;
}
  1. invokeAwareMethods:如果當前 bean 實現了 Aware 接口,那么 Aware 接口相關的方法就在 invokeAwareMethods 方法中被觸發。
  2. applyBeanPostProcessorsBeforeInitialization:這個是執行 BeanPostProcessor#postProcessBeforeInitialization 方法。
  3. invokeInitMethods:這個里邊是干兩件事,如果我們的 Bean 實現了 InitializingBean 接口,那么該接口中的 afterPropertiesSet 方法就在這里被觸發;另一方面就是如果我們通過配置文件 Bean 的初始化方法(XML 文件中的 init-method 屬性),那么也會在這里被觸發。
  4. applyBeanPostProcessorsAfterInitialization:這個是執行 BeanPostProcessor#postProcessAfterInitialization 方法。

這里需要注意的一點是,通過在 XML 文件中配置的 init-method 屬性,這個是在第 3 步被觸發執行的;但是如果是通過 @PostConstruct 注解標記的 Bean 的初始化方法,則是通過 BeanPostProcessor 來處理的,具體是在 InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization 方法中處理的。這兩種看起來作用類似的 Bean 初始化方法,底層處理邏輯并不相同。

初始化完成之后,還有一個關于循環依賴的處理和判斷。

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.");
   }
  }
 }
}

這段代碼主要是防止 Spring 容器中創建出來的當前 Bean 和被其他 Bean 所依賴的 Bean 不是同一個。例如有 A 和 B 兩個類,Spring 根據既有配置,給 A 生成了代理類,但是 B 引用的并不是 A 的代理對象,而是 A 的原始對象,此時就會有問題。所以這里主要是去判斷,確保容器中和被使用的 A 是同一個。

檢查的思路就是先去二級緩存中查找,二級緩存中如果存在,說明這個 Bean 因為循環依賴的原因已經被引用過了(被引用過的 Bean 會存入到二級緩存中),此時去判斷 exposedObject 和 bean 是否為同一個 Bean,正常情況下,這兩個當然是同一個 Bean,因為 exposedObject 和 bean 指向同一個內存地址。什么情況下,這兩個 Bean 會不同呢?如果在 Bean 的后置處理器中,我們使用新的 Bean 替換了舊的 Bean,就會導致最終拿到的 exposedObject 和 bean 兩個變量指向的地址不再相同。如果不相同,就要檢查當前 Bean 是否有被容器中的其他 Bean 所依賴了,如果有,并且使用了當前 Bean 的 Bean 還正在創建中,那么就趕緊刪除掉重新創建,如果使用了當前 Bean 的 Bean 已經創建完成了,那就沒辦法了,只能拋出異常了。

4. 銷毀

銷毀并不是說要立馬把 Bean 給銷毀掉,這 Bean 剛創建出來還沒使用呢,怎么就給銷毀了呢?

這里的銷毀是說把 Bean 的銷毀方法先記錄下來,將來需要銷毀 Bean 或者銷毀容器的時候,就調用這些方法去釋放 Bean 所持有的資源。

// Register bean as disposable.
try {
 registerDisposableBeanIfNecessary(beanName, bean, mbd);

Bean 的銷毀方法我們可以通過注解或者是 XML 文件進行配置。使用注解的話就是 @PreDestroy 注解,被該注解標記的方法可以在 Bean 銷毀之前執行,我們可以在該方法中釋放資源;也可以使用 XML 文件進行配置 destroy-method="",通過該屬性指定 Bean 銷毀時候需要執行的方法。另外,當前 Bean 也可以通過實現 DisposableBean 接口,并重寫該接口中的 destroy 方法,那么容器銷毀的時候,這個方法會被自動調用以釋放資源。

除了這三種常見的方法之外,還有一個辦法就是如果當前 Bean 實現了 AutoCloseable 接口,那么當前類中如果存在名為 close 的方法或者名為 shutdown 的方法,那么對應的方法就會被自動調用。

好啦,大致的流程就是這樣了,小伙伴們不妨據此畫一個流程圖看看。

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2022-10-19 23:28:55

Spring生命周期Bean

2023-02-15 16:25:06

機器學習人工智能數據

2024-05-28 07:55:31

SpringBean用域

2022-09-05 07:06:59

BeanSpring

2024-09-09 08:29:25

2011-04-19 09:27:25

Spring

2020-09-08 06:54:29

Java Gradle語言

2022-03-14 08:54:42

SpringBean生命周期

2023-07-06 13:56:14

微軟Skype

2021-12-08 11:18:21

Spring Bean面試題生命周期

2020-02-10 19:34:12

生命周期流程流程圖

2025-06-03 04:00:00

Spring框架配置

2018-06-07 13:17:12

契約測試單元測試API測試

2021-01-28 22:31:33

分組密碼算法

2023-09-22 17:36:37

2020-05-22 08:16:07

PONGPONXG-PON

2020-06-10 07:38:30

Spring框架周期

2023-09-20 23:01:03

Twitter算法

2021-12-06 09:43:01

鏈表節點函數

2021-07-16 11:48:26

模型 .NET微軟
點贊
收藏

51CTO技術棧公眾號

www.久久色| 久久久美女视频| 午夜av成人| 中文字幕国产精品一区二区| 91视频国产高清| 精品无码av在线| 国产不卡av一区二区| 欧美久久一区二区| 久久久亚洲国产精品| 黄色av网址在线免费观看| 毛片av中文字幕一区二区| 欧美国产日本高清在线 | 国产又黄又大又粗的视频| 日韩欧美不卡| 欧美精品一区二区三区高清aⅴ| 日本在线观看a| 麻豆影视在线观看_| www.欧美日韩| 成人网在线免费观看| 精品欧美一区二区三区免费观看| 四虎成人av| 亚洲精品久久久久久久久久久| 第四色婷婷基地| 91福利在线免费| 国产精品久久久久久亚洲毛片 | 国内一区二区在线| 国产精品99久久久久久久久久久久| 亚洲伦理一区二区三区| 久操成人av| 亚洲国产精品va在线观看黑人| 性欧美videossex精品| 91豆花视频在线播放| 亚洲视频综合在线| 色大师av一区二区三区| 天天色综合av| 国产大陆精品国产| 91精品视频在线| 亚洲免费视频二区| 午夜在线一区二区| 午夜欧美不卡精品aaaaa| 国精品无码一区二区三区| 国产影视精品一区二区三区| 亚洲精品日韩在线| 日批在线观看视频| 一区二区免费| 日韩你懂的在线观看| 亚洲一级片av| 日韩亚洲国产免费| 欧美日韩免费观看一区二区三区| 青青在线视频免费| 欧美黑人粗大| 一本色道综合亚洲| 北条麻妃在线观看| 蜜桃视频www网站在线观看| 亚洲一区二区美女| 美女黄色免费看| 伊人福利在线| 精品久久国产一区| 国产欧美精品一区| 欧洲精品久久| 日韩欧美电影在线观看| 成人小视频在线| 成人av网站观看| 精品国产999久久久免费| 国产乱码精品一区二区三区忘忧草| 成人激情视频网| 国产一区二区三区三州| 国内精品免费**视频| 亚洲a中文字幕| 精品国产av一区二区三区| 国产福利一区在线| 高清一区二区三区视频| 成人免费视频国产免费麻豆| 成人国产精品免费网站| 国产在线视频欧美一区二区三区| 性高潮久久久久久久久久| 91视频观看免费| 欧美精品久久| 四虎久久免费| 一区二区三区中文字幕精品精品 | 国产人妖ts一区二区| 亚洲丁香久久久| 双性尿奴穿贞c带憋尿| 国产精品欧美日韩一区| 视频在线一区二区| 强行糟蹋人妻hd中文| 99精品视频网| 国产激情视频一区| 国产精品丝袜黑色高跟鞋| 国产成人在线观看免费网站| 国产区欧美区日韩区| 久久久资源网| 亚洲三级理论片| 男女超爽视频免费播放| 亚洲精品国产嫩草在线观看| 欧美一区二区在线免费播放| 国产精品无码一区二区三| 欧美伦理在线视频| 欧美日本精品在线| 一级片免费在线播放| 精品一区二区三区不卡| 国产一区二区三区无遮挡| 国产一级片在线| 亚洲美女偷拍久久| 欧美黄色一级片视频| 动漫一区二区三区| 亚洲色图18p| 欧美人妻精品一区二区三区| 美女视频一区免费观看| 3d动漫啪啪精品一区二区免费| 三级视频在线播放| 亚洲精品乱码久久久久久日本蜜臀| 久在线观看视频| 91成人在线网站| 亚洲欧美激情四射在线日| 五月天av网站| 秋霞午夜av一区二区三区| 成人片在线免费看| 九七电影韩国女主播在线观看| 欧美午夜www高清视频| 99视频在线观看视频| 国产99久久| 国色天香2019中文字幕在线观看| 正在播放亚洲精品| 久久久久久久综合| 18禁裸男晨勃露j毛免费观看| 农村妇女一区二区| 亚洲欧美综合另类中字| 国产亚洲精品成人| 国产一区二区在线影院| 视频一区视频二区视频三区高| av电影免费在线看| 欧美大片在线观看一区二区| 日本不卡一二区| 日韩和的一区二区| 快播亚洲色图| 欧美a级在线观看| 精品国产sm最大网站免费看| 小早川怜子一区二区的演员表| 久久亚洲精品伦理| 精品人伦一区二区三区| 欧美日韩经典丝袜| 日韩精品中文字幕一区二区三区| 91精品国产闺蜜国产在线闺蜜| 日韩av电影天堂| 日韩免费av电影| 日韩久久一区二区三区| 日韩精品在线看| av资源免费观看| 波多野结衣中文一区| 免费看欧美黑人毛片| 动漫视频在线一区| 不卡av电影在线观看| 国产精品久久久久久在线| 中文字幕一区二区在线观看| 一本色道久久亚洲综合精品蜜桃| 欧美日韩一二| 国产精品视频区1| 最新国产在线观看| 911精品国产一区二区在线| 国产精品国产精品88| 国产一本一道久久香蕉| 97av中文字幕| 国产劲爆久久| 青青在线视频一区二区三区| 日本一本草久在线中文| 欧美性生交xxxxxdddd| 免费黄色在线视频| 日韩不卡手机在线v区| 亚洲欧洲一二三| 超碰国产精品一区二页| 欧美成年人视频网站| 亚洲精品久久久久久无码色欲四季| 亚洲成人免费视频| 色婷婷av777| 久久99国产精品久久99| 亚洲天堂第一区| eeuss国产一区二区三区四区| 97色伦亚洲国产| 久久手机免费观看| 在线播放91灌醉迷j高跟美女| 欧美日韩偷拍视频| 久久这里只有精品6| 天天色综合天天色| 欧美伊人影院| 精品999在线观看| 欧美成人app| 欧美激情区在线播放| 欧美大片aaa| 欧美精品三级在线观看| 国产一级做a爱免费视频| 91免费国产视频网站| 亚洲一区精品视频在线观看| 国产一区二区三区自拍 | 免费av一区二区三区四区| 国产精品视频一区二区三区四| а√天堂官网中文在线| 日韩精品福利在线| 国产精品久久久久久免费播放| 午夜日韩在线电影| www.黄色com| 99精品1区2区| 日本高清一区二区视频| 国产精品社区| 国产一级大片免费看| 精品久久久久久久久久久aⅴ| 91色在线视频| 全球最大av网站久久| 午夜欧美大片免费观看| 久草中文在线| 国产一区二区三区免费视频| 丰满熟妇乱又伦| 欧美日韩免费观看一区三区| 日韩精品一区二区在线播放 | 99久久精品无码一区二区毛片| 国产综合色区在线观看| 国产69精品久久久久99| 麻豆视频在线免费观看| 亚洲欧美国产一区二区三区| www.午夜激情| 欧美日韩国产另类一区| 69亚洲精品久久久蜜桃小说| 一区二区欧美精品| 99久久99久久精品免费看小说.| 99久久伊人久久99| gogo亚洲国模私拍人体| 麻豆freexxxx性91精品| 成年网站在线免费观看| 亚洲欧洲视频| 日韩欧美视频免费在线观看| 91综合网人人| 视频一区二区在线| 国产精品日韩精品中文字幕| 国产日韩欧美亚洲一区| 成人av地址| 97人摸人人澡人人人超一碰| 久久久久久爱| 91久久国产婷婷一区二区| 色8久久久久| 国产欧美一区二区三区四区| 欧美123区| 国产精品青草久久久久福利99| 都市激情亚洲综合| 欧美中文字幕第一页| 国内激情视频在线观看| 国内自拍欧美激情| av2020不卡| 性欧美长视频免费观看不卡| 波多野结衣在线播放| 欧美精品久久久久久久久久| 女同视频在线观看| 欧美激情一区二区三区高清视频| 羞羞网站在线免费观看| 欧美精品一区二区免费| 欧美四级在线| 97久久精品视频| 在线黄色的网站| 日本国产高清不卡| 久久久成人av毛片免费观看| 国产精品99久久久久久久久久久久| av有声小说一区二区三区| 国产精品丝袜久久久久久不卡| julia一区二区三区中文字幕| 国产精品美女在线| 色综合视频一区二区三区日韩| 亚洲淫片在线视频| 日韩中文字幕在线一区| 国产伦精品一区二区三区视频黑人| 久久97久久97精品免视看秋霞| 久久99国产精品99久久| 精品国产精品国产偷麻豆| 欧美在线一二三区| 希岛爱理一区二区三区| 国产一级黄色录像片| 日韩视频一区| 亚洲三级视频网站| 国产精品一级二级三级| 成人性生活免费看| 国产人成亚洲第一网站在线播放| 国产精品麻豆免费版现看视频| 一区二区三区欧美久久| 日韩xxxxxxxxx| 在线观看欧美黄色| va视频在线观看| 日韩精品免费在线视频| 伊人在线视频| 欧美激情精品久久久久久| 爱情电影社保片一区| 成人网中文字幕| 林ゆな中文字幕一区二区| 日韩精品一线二线三线| 欧美一区二区| 久久九九国产视频| 国产一二三精品| 色一情一交一乱一区二区三区 | 日韩欧美成人一区| 精品久久久久一区二区三区| 久久久精品免费视频| 久久男人天堂| 国产啪精品视频| 欧美精品中文| 日韩视频在线观看视频| 一本色道久久综合亚洲精品高清| 911福利视频| 久久免费美女视频| 男女免费视频网站| 欧美日韩卡一卡二| 亚洲三区在线播放| 欧美成人精品激情在线观看| 日韩欧美一区二区三区在线观看| 99国产盗摄| 91综合网人人| 国产成人手机视频| 成人app下载| 精品自拍偷拍视频| 欧美亚洲一区三区| 香蕉久久国产av一区二区| 欧美成人一区二区三区电影| 国产电影一区二区三区爱妃记| 国产精品日韩欧美一区二区| 91精品啪在线观看国产18 | 欧美日韩国产观看视频| 亚洲一区二区三区毛片| 欧美日韩国产高清电影| 成人av一级片| 丁香婷婷综合网| 男女做暖暖视频| 欧美丝袜丝交足nylons| 欧美18xxxxx| 97av在线影院| 91精品久久久久久综合五月天| 中文字幕一区二区三区有限公司| 日韩激情av在线| 91成人在线免费视频| 激情懂色av一区av二区av| 亚洲精品无遮挡| 欧美俄罗斯性视频| 亚洲精品在线播放| 蜜桃网站在线观看| 国产在线精品免费| 欧美手机在线观看| 717成人午夜免费福利电影| 午夜精品一区| 91久久精品国产91久久| 婷婷综合视频| 国产成人美女视频| 中文字幕一区二区三区av| 中文字幕日韩第一页| 中文字幕日韩av| 成人毛片免费| 亚洲一区二区在线看| 精品一区二区三区不卡| h色网站在线观看| 欧美一区二区三区男人的天堂| 麻豆传媒视频在线观看免费| 国产日韩欧美中文| 91精品一区二区三区综合| 91丝袜超薄交口足| 玉米视频成人免费看| 亚洲AV无码乱码国产精品牛牛| 欧美寡妇偷汉性猛交| 久久免费视频66| wwwxxx黄色片| 国产欧美精品一区二区色综合| 中国a一片一级一片| x99av成人免费| 免费看日产一区二区三区| h无码动漫在线观看| 99久久婷婷国产精品综合| 国产精品一区无码| 尤物九九久久国产精品的特点| 欧洲精品久久久久毛片完整版| 老司机午夜免费福利视频| 成人午夜视频在线观看| 欧美一级片免费在线观看| 亚洲午夜精品视频| www.久久草.com| 91精品国产91久久久久麻豆 主演| 99久久er热在这里只有精品66| 一级黄色大片视频| 久久久国产精品一区| 国产成人精品福利| 日韩精品一区二区三区色欲av| 中文字幕高清不卡| 亚洲xxx在线| 日韩av手机在线观看| 国产精品久久久久久久| 国产精品一区二区无码对白| 色哟哟欧美精品| 国产cdts系列另类在线观看| 99在线热播| 日本成人中文字幕| 欧美成人综合色| 国产亚洲aⅴaaaaaa毛片| 免费精品一区二区三区在线观看| 黑人糟蹋人妻hd中文字幕| 中文字幕字幕中文在线中不卡视频| 国产 欧美 自拍| 国产精品视频男人的天堂| 亚洲激情av|