java面試題核心篇(三)

LNhome發表於2018-03-28

Spring

1、BeanFactory 和 ApplicationContext 有什麼區別

ApplicationContext由BeanFactory 派生而來,原始的BeanFactory無法支援spring的許多外掛,如AOP功能、Web應用等。ApplicationContext包還提供了以下的功能:
(1)利用MessageSource進行國際化  
(2)強大的事件機制(Event)
(3)底層資源的訪問,ApplicationContext擴充套件了ResourceLoader(資源載入器)介面,從而可以用來載入多個Resource,而BeanFactory是沒有擴充套件ResourceLoader 
(4)對Web應用的支援,與BeanFactory通常以程式設計的方式被建立不同的是,ApplicationContext能以宣告的方式建立,如使用ContextLoader。當然你也可以使用ApplicationContext的實現之一來以程式設計的方式建立ApplicationContext例項 。 
(5)BeanFactroy採用的是延遲載入形式來注入Bean的,而ApplicationContext則相反,它是在容器啟動時,一次性建立了所有的Bean。BeanFactory和ApplicationContext都支援BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區別是:BeanFactory需要手動註冊,而ApplicationContext則是自動註冊


2、Spring Bean 的生命週期

(1)例項化一個Bean,也就是我們通常說的new。
(2)按照Spring上下文對例項化的Bean進行配置,也就是IOC注入。
(3)如果這個Bean實現了BeanNameAware介面,會呼叫它實現的setBeanName(String beanId)方法,此處傳遞的是Spring配置檔案中Bean的ID。
(4)如果這個Bean實現了BeanFactoryAware介面,會呼叫它實現的setBeanFactory(),傳遞的是Spring工廠本身(可以用這個方法獲取到其他Bean)。
(5)如果這個Bean實現了ApplicationContextAware介面,會呼叫setApplicationContext(ApplicationContext)方法,傳入Spring上下文,該方式同樣可以實現步驟4,但比4更好,以為ApplicationContext是BeanFactory的子介面,有更多的實現方法。
(6)如果這個Bean關聯了BeanPostProcessor介面,將會呼叫postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor經常被用作是Bean內容的更改,並且由於這個是在Bean初始化結束時呼叫After方法,也可用於記憶體或快取技術。
(7)如果這個Bean在Spring配置檔案中配置了init-method屬性會自動呼叫其配置的初始化方法。
(8)如果這個Bean關聯了BeanPostProcessor介面,將會呼叫postAfterInitialization(Object obj, String s)方法,注意:以上工作完成以後就可以用這個Bean了,那這個Bean是一個single的,所以一般情況下我們呼叫同一個ID的Bean會是在內容地址相同的例項
(9)當Bean不再需要時,會經過清理階段,如果Bean實現了DisposableBean介面,會呼叫其實現的destroy方法。
(10)最後,如果這個Bean的Spring配置中配置了destroy-method屬性,會自動呼叫其配置的銷燬方法。
這裡描述的是應用Spring上下文Bean的生命週期,如果應用Spring的工廠也就是BeanFactory的話去掉第5步就Ok了。
3、Spring IOC 如何實現
IOC概述:
所有的類都會在spring容器中登記,告訴spring你是個什麼東西,你需要什麼東西,然後spring會在系統執行到適當的時候,把你要的東西主動給你,同時也把你交給其他需要你的東西。所有的類的建立、銷燬都由 spring來控制,也就是說控制物件生存週期的不再是引用它的物件,而是spring。對於某個具體的物件而言,以前是它控制其他物件,現在是所有物件都被spring控制,所以這叫控制反轉。
IoC的一個重點是在系統執行中,動態的向某個物件提供它所需要的其他物件。這一點是通過DI(Dependency Injection,依賴注入)來實現的。比如物件A需要運算元據庫,以前我們總是要在A中自己編寫程式碼來獲得一個Connection物件,有了 spring我們就只需要告訴spring,A中需要一個Connection,至於這個Connection怎麼構造,何時構造,A不需要知道。在系統執行時,spring會在適當的時候製造一個Connection,然後像打針一樣,注射到A當中,這樣就完成了對各個物件之間關係的控制。A需要依賴 Connection才能正常執行,而這個Connection是由spring注入到A中的,依賴注入的名字就這麼來的。那麼DI是如何實現的呢? Java 1.3之後一個重要特徵是反射(reflection),它允許程式在執行的時候動態的生成物件、執行物件的方法、改變物件的屬性,spring就是通過反射來實現注入的。


4、說說 Spring AOP

AOP的基本概念
(1)Aspect(切面):通常是一個類,裡面可以定義切入點和通知
(2)JointPoint(連線點):程式執行過程中明確的點,一般是方法的呼叫
(3)Advice(通知):AOP在特定的切入點上執行的增強處理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入點):就是帶有通知的連線點,在程式中主要體現為書寫切入點表示式
(5)AOP代理:AOP框架建立的物件,代理就是目標物件的加強。Spring中的AOP代理可以使JDK動態代理,也可以是CGLIB代理,前者基於介面,後者基於子類
橫向地散佈在所有物件層次中,而與它對應的物件的核心功能毫無關係對於其他型別的程式碼,如安全性、異常處理和透明的持續性也都是如此,這種散佈在各處的無關的程式碼被稱為橫切(cross cutting),在OOP設計中,它導致了大量程式碼的重複,而不利於各個模組的重用。AOP技術恰恰相反,它利用一種稱為"橫切"的技術,剖解開封裝的物件內部,並將那些影響了多個類的公共行為封裝到一個可重用模組,並將其命名為"Aspect",即切面。所謂"切面",簡單說就是那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組之間的耦合度,並有利於未來的可操作性和可維護性。使用"橫切"技術,AOP把軟體系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處基本相似,比如許可權認證、日誌、事物。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。


5、Spring AOP 實現原理

Spring AOP採用動態代理和CGlib動態位元組碼生成兩種方式實現,動態代理只能對實現了相應Interface的類使用,如果某個類沒有實現任何的Interface,就無法使用動態代理對其產生相應的代理物件! CGLIB擴充套件物件行為的原理是:對目標物件進行繼承擴充套件,為其生成相應的子類,而子類可以通過覆寫來擴充套件父類的行為,只要將橫切邏輯的實現放到子類中,然後讓系統使用擴充套件後的目標物件的子類,就可以達到與代理模式相同的效果了。


6、動態代理(cglib 與 JDK)

JDK動態代理所用到的代理類在程式呼叫到代理類物件時才由JVM真正建立,JVM根據傳進來的 業務實現類物件 以及 方法名 ,動態地建立了一個代理類的class檔案並被位元組碼引擎執行,然後通過該代理類物件進行方法呼叫。我們需要做的,只需指定代理類的預處理、呼叫後操作即可。JDK動態代理的代理物件在建立時,需要使用業務實現類所實現的介面作為引數(因為在後面代理方法時需要根據介面內的方法名進行呼叫)。如果業務實現類是沒有實現介面而是直接定義業務方法的話,就無法使用JDK動態代理了。並且,如果業務實現類中新增了介面中沒有的方法,這些方法是無法被代理的(因為無法被呼叫)。
cglib是針對類來實現代理的,原理是對指定的業務類生成一個子類,並覆蓋其中業務方法實現代理。因為採用的是繼承,所以不能對final修飾的類進行代理。 


7、事務的四個原則(ACID):

原子性,一致性,隔離性,永續性


8、事務的型別:

(1)資料庫分為本地事務跟全域性事務,本地事務:普通事務,獨立一個資料庫,能保證在該資料庫上操作的ACID。分散式事務:涉及兩個或多個資料庫源的事務,即跨越多臺同類或異類資料庫的事務(由每臺資料庫的本地事務組成的),分散式事務旨在保證這些本地事務的所有操作的ACID,使事務可以跨越多臺資料庫。
(2)Java事務型別分為JDBC事務跟JTA事務,JDBC事務:即為上面說的資料庫事務中的本地事務,通過connection物件控制管理。JTA指Java事務API(Java Transaction API),是Java EE資料庫事務規範, JTA只提供了事務管理介面,由應用程式伺服器廠商(如WebSphere Application Server)提供實現,JTA事務比JDBC更強大,支援分散式事務。
(3)按是否通過程式設計分為宣告式事務和程式設計式事務。


9、Spring的傳播行為:

(1)PROPAGATION_REQUIRED:支援當前事務,如當前沒有事務,則新建一個。
(2)PROPAGATION_SUPPORTS:支援當前事務,如當前沒有事務,則已非事務性執行。
(3)PROPAGATION_MANDATORY:支援當前事務,如當前沒有事務,則丟擲異常(強制一定要在一個已經存在的事務中執行,業務方法不可獨自發起自己的事務)。
(4)PROPAGATION_REQUIRES_NEW:始終新建一個事務,如當前原來有事務,則把原事務掛起。
(5)PROPAGATION_NOT_SUPPORTED:不支援當前事務,始終已非事務性方式執行,如當前事務存在,掛起該事務。
(6)PROPAGATION_NEVER:不支援當前事務;如果當前事務存在,則引發異常。
(7)PROPAGATION_NESTED:如果當前事務存在,則在巢狀事務中執行,如果當前沒有事務,則執行與 PROPAGATION_REQUIRED 類似的操作(注意:當應用到JDBC時,只適用JDBC 3.0以上驅動)。


10、Spring 事務實現方式:

編碼方式實現事務管理和宣告式事務

11、Spring 事務底層原理:

(1)劃分處理單元——IOC由於spring解決的問題是對單個資料庫進行區域性事務處理的,具體的實現首相用spring中的IOC劃分了事務處理單元。並且將對事務的各種配置放到了ioc容器中(設定事務管理器,設定事務的傳播特性及隔離機制)。
(2)AOP攔截需要進行事務處理的類,Spring事務處理模組是通過AOP功能來實現宣告式事務處理的,具體操作(比如事務實行的配置和讀取,事務物件的抽象),用TransactionProxyFactoryBean介面來使用AOP功能,生成proxy代理物件,通過TransactionInterceptor完成對代理方法的攔截,將事務處理的功能編織到攔截的方法中。讀取ioc容器事務配置屬性,轉化為spring事務處理需要的內部資料結構(TransactionAttributeSourceAdvisor),轉化為TransactionAttribute表示的資料物件。
(3)對事物處理實現(事務的生成、提交、回滾、掛起),spring委託給具體的事務處理器實現。實現了一個抽象和適配。適配的具體事務處理器:DataSource資料來源支援、hibernate資料來源事務處理支援、JDO資料來源事務處理支援,JPA、JTA資料來源事務處理支援。這些支援都是通過設計PlatformTransactionManager、AbstractPlatforTransaction一系列事務處理的支援。為常用資料來源支援提供了一系列的TransactionManager。
(7)結合,PlatformTransactionManager實現了TransactionInterception介面,讓其與TransactionProxyFactoryBean結合起來,形成一個Spring宣告式事務處理的設計體系。


12、如何自定義註解實現功能:

使用@interface關鍵字定義註解,

13、SpringMVC執行流程:

(1)使用者傳送請求至前端控制器DispatcherServlet。
(2)DispatcherServlet收到請求呼叫HandlerMapping處理器對映器。
(3)處理器對映器根據請求url找到具體的處理器,生成處理器物件及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
(4)DispatcherServlet通過HandlerAdapter處理器介面卡呼叫處理器。
(5)執行處理器(Controller,也叫後端控制器)。
(6)Controller執行完成返回ModelAndView。
(7)HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。
(8)DispatcherServlet將ModelAndView傳給ViewReslover檢視解析器。
(9)ViewReslover解析後返回具體View。
(10)DispatcherServlet對View進行渲染檢視(即將模型資料填充至檢視中)。
(11)DispatcherServlet響應使用者。


13、Spring MVC 啟動流程:

(1)ContextLoaderListener初始化,例項化IoC容器,並將此容器例項註冊到ServletContext中。
(2)DispatcherServlet初始化,建立自己的上下文,也註冊到ServletContext中。

14、Spring 的單例實現原理

Spring對bean例項的建立是採用單例登錄檔的方式進行實現的,而這個登錄檔的快取是HashMap物件,如果配置檔案中的配置資訊要求不使用單例,Spring會採用新建例項的方式返回物件例項。


15、Spring 框架中用到了哪些設計模式:

工廠模式、單例模式、介面卡模式、代理模式、觀察者模式、策略模式、模板模式、包裝器模式

相關文章