1. 程式人生 > >工作5年了還說不清bean生命週期?大廠offer怎麼可能給你!

工作5年了還說不清bean生命週期?大廠offer怎麼可能給你!

第一,這絕對是一個面試高頻題。

 

比第一還重要的第二,這絕對是一個讓人愛恨交加的面試題。為什麼這麼說?我覺得可以從三個方面來說:

  1. 先說會不會。看過原始碼的人,這個不難;沒看過原始碼的人,無論是學、硬背、還是說,絕對是一個坎。

  2. 再說考察點。這個問題還是比較開放的。可以用三五句話講出來,也可以揪著面試官聊半個小時。

  3. 最後說效果。說的不好,絕對“狠減分”;說的好了,也絕對“狠加分”。

     

所以說,遇到這個問題,要麼顫抖著死去,要麼就需要你有強大的忍住不笑了的能力(這個梗可懂)。

 

好吧好吧,既然都這麼“硬核”了,我們沒有理由不拿下。

 

接下來我嘗試站在面試官的角度來分析,“他們”想考察的知識點,摸清了套路,再設法一點點的去“餵飽”面試官。

 

第一層:簡單回答問題

 

面試官心裡分析:

 

作為面試官,我提這個問題,想知道你是否有看原始碼的習慣或者說經歷。通過你的回答,我能初步判斷出,你平時是滿足於“CRUD”完成需求?還是有好奇心去尋找底層是如何實現的?進而我也就能預判,如果招你進來,是一個偏執行性的人,還是能在團隊中承擔更多的責任,能主動探究和發現問題。

 

其實這相當於面試官給我們畫好的圈子,只要我們提出幾個關鍵點,即可證明我們看過。

 

非主流標準答案:

 

part1.

在真正開始bean的生命週期之前,會讀取資原始檔,生成BeanDefinition物件。BeanDefinition是bean的前生,bean是BeanDefinition的今世。BeanDefinition除了像Class那樣描述了屬性方法之類的外,還描述bean的其他特性,比如,是否單例,依賴關係等

 

part2.

在整個生命週期中,主要就是兩件事,bean的建立和賦值以及依賴關係的注入;通過各個擴充套件點豐富bean的能力,比如BeanFactoryPostProcessor、BeanPostProcessor等。

 

第二層:展露亮點

 

面試官心裡分析:

 

僅僅達到目標我們就滿足了嗎?當然不能,我們追求的,是卓越!如果我們能借助一個類似流程圖之類的框架,把bean生命週期在最短的時間內,清晰,簡明的描述出來,這就是讓面試官眼前一亮的亮點。我會覺得你,除了好奇心和自驅力外,理解和總結能力也不錯,以後我們稱為同事溝通時,不會讓我覺得經常雞同鴨講(別告訴我你沒遇到過這種人,給他把方案講三兩遍,一直在點頭,等做出來的活發現還是南轅北轍,這絕對不是笑話)。

 

非主流標準答案:

 

part1.

bean的生命週期,主要經歷4個階段,4類擴充套件。分別結合兩張圖來說明,先來看下4個階段:

 

說明:怎麼理解這個過程呢?

 

  •  類比我們自己構造一個物件,也是先呼叫建構函式建立,然後通過setter為屬性賦值。分別對應了上圖中的【例項化】和【為Bean屬性賦值。

     

  • 這裡提了初始化環節,該環節對應執行的,是我們在定義bean(比如xml配置,比如註解中配置)時,配置的init方法。

     

  • 最後一個登出,就更好理解了,在Java出現之前的C時代,是需要程式設計師自己管理記憶體的,那麼在分配記憶體建立物件後,是需要自己登出物件釋放記憶體的。那麼既然已經在Java裡了為什麼還要明確的有這個環節呢?我理解,作為框架,首先不能完全依賴GC來回收物件,這樣太被動了;另外,我都是框架了,框架二字意味著什麼?超強的整合能力!翻譯成人話就是,你想要的都在這,你想做什麼我都給你留了“後門”(介面)。,那當你想在這個環節搞點什麼事情的時候,卻發現我無能為力,豈不是尬了?

     

part2.

接下來再來看4類擴充套件。所謂擴充套件,首先我們簡單的理解下,無非就是提供了一系列的介面,你只要實現這些介面,就能在整個生命週期的某一個節點,執行你實現的方法邏輯,在這個方法裡呢,可以拿到xxx物件(比如ApplicationContext,比如BeanDefinition,比如Bean等等);然後對這些物件做點什麼。還是來看下圖:

 

 

        

請看上圖,一個色系代表一類介面。

 

  1.  BeanFactoryPostProcessor介面,實現該介面可以拿到BeanDefinition,可以做修改。

     

  2. BeanPostProcessor介面,上圖中的InstantiationAwareBeanPostProcessor是其子介面,所以都歸為一類,都是和建立bean相關的。

     

  3. xxxAware介面,比如BeanNameAware,BeanFactoryAware,ApplicationContextAware,拿ApplicationContextAware來說,可以獲取當前上下文,然後進而拿到bean的例項,進行處理。

     

  4. xxxBean介面,有三個典型應用:

     

    1. FactoryBean:能生產bean的工廠。

    2. InitializingBean:初始化bean時候可進行擴充套件

    3. DiposibleBean:登出bean時候可進行的擴充套件

第三層:釋放個人魅力

 

面試官心裡分析:

 

在講清流程的基礎上,如果你還能說一說框架在現實中的應用就更上一層樓了,我會認為你在工作中遇到問題時,工具箱裡可選的工具更多。這無論從哪個角度來看,都能為團隊帶來正向的收益。

 

非主流標準答案:

 

    1.  BeanFactoryPostProcessor介面應用:

       

      1. mybatis,就是實現該介面的子介面,來通過mapper介面和xml中的sql,生成對應的類的BeanDefinition,這樣在使用時,就不用自己在寫連線資料庫,建立Session,執行查詢等等邏輯了。

         

      2. 在spring-boot中,入口方法在標註了@Configuration註解的類中,那這個方法是如何注入到spring中的呢?掃描標註該註解的邏輯,就是寫在實現了BeanFactoryPostProcessor介面的子介面的例項裡。

         

      3. 還有直接實現BeanFactoryPostProcessor介面的,比如我們定義的DataSource中的佔位符,替換成實際的值。

         

    2. BeanPostProcessor介面的應用:

       

      1. AOP中需要在建立例項前判斷是否需要建立代理物件,相當於是阻斷了例項的建立。就是在實現InstantiationAwareBeanPostProcessor介面的例項中實現的,執行的是xxxBefore()方法

         

      2. 我們常用@AutoAware註解,引入一個bean,其依賴注入就是在InstantiationAwareBeanPostProcessor.xxxPropertyValues()方法中實現的。

         

其他的,暫時不在這裡列出,既然你看到了這篇文章,那麼也參與進來,我們一起補全。

如果看的還算過癮,關注這個公號,我們接著聊。

&n