java面試題 --- Spring①

1. Spring 有哪些特點?

  • 輕量級:不管是 spring 的代碼量還是運行所需要的開銷,都算是輕量級的;
  • 控制反轉:控制反轉就是創建對象的權利轉交給 spring,程序要用的時候注入就行,降低了耦合度;
  • 面向切面:將與業務無關卻影響多個對象的代碼抽取出來,形成切面。

2. Spring 的核心模塊有哪些?

Spring 有七大核心模塊:

  • Spring core:核心模塊,提供 Spring 的基礎功能;
  • Spring Aop:提供了對面向切面編程的支持;
  • Spring Context:應用上下文模塊,向 Spring 框架提供上下文信息;
  • Spring Dao:提供了數據庫操作的基礎結構;
  • Spring ORM:提供了對持久層框架的支持;
  • Spring Web:提供了對 web 開發的支持,基於 web 程序提供上下文;
  • Spring Web MVC:構建 web 應用程序的 MVC 實現。

3. 什麼是 Spring ioc?

  • IOC 就是控制反轉,創建對象的權力交給 Spring,要用的時候直接從 IOC 容器中取出即可。它最核心的就是refresh方法,其包含了13個核心方法,大體流程是:首先會判斷當前有沒有 beanFactory 容器,如果沒有,就創建 beanFactory 容器,然後通過 BeanDefinitionReader 對象讀取配置文件或者註解,將配置都封裝成 BeanDifinition 對象,再通過 BeanFactoryPostProcessor 來完成對 beanFactory 信息的修改或者擴展。然後會準備好 beanPostProcessor,監聽器,廣播器等,之後通過反射執行實例化操作,接着是進行 bean 的初始化,包括用 populateBean 方法填充屬性,執行 aware 接口的方法,給 bean 設置所需要的容器內置的bean;接着執行 beanPostProcessor 來完成對 bean 的修改或者擴展,最後生成一個完整對象。AOP 功能就是通過 BeanPostProcessor 來實現的。

4. 說一說循環依賴怎麼解決。

-循環依賴就是 A 對象有屬性 b,B 對象有屬性 A,這就是循環依賴。假如通過構造方法創建對象,創建 A 的時候要傳入 B,B 又還沒有,就得創建,創建 B 又得傳入 A,這樣就會無限套娃,所以 Spring 只能解決 setter 注入的循環依賴問題。它是用三級緩存解決的,其實也就是三個 map,一級緩存保存的是成品對象;二級緩存保存的是半成品對象,即實例化了但是屬性還沒賦值的對象;三級緩存保存的是 lambda 表達式。解決三級緩存的流程爲:創建 A 對象之前,就會判斷緩存中有沒有 A,如果沒有,就會創建 A 對象,在給 A 對象屬性賦值之前,就會調用 addSingletonFactory 方法,該方法傳入一個 lambda 表達式,與此同時會把這個 lambda 表達式放進三級緩存中;接着填充屬性,發現屬性 b 爲空,就會實例化 B,實例化 B 和實例化 A 流程一樣,在給 b 填充屬性的時候,發現 a 爲空,但是三級緩存中有 a 對象的 lambda 表達式,然後就會執行這段表達式,就得到了 a 對象,半成品 a 對象就會放到二級緩存中。賦值完的 b 對象,就是一個成品對象了,就會放到一級緩存中,回去再給 a 對象的 b 屬性賦值時,就直接從一級緩存中取出 b 對象,賦值完的 a 對象也是一個成品對象了,也會放到一級緩存中。如果沒有用到 aop,則用兩級緩存,也可以解決循環依賴問題,如果用到了 aop,必須要三級,因爲兩級緩存無法區分對象的版本。


5. Spring bean 是安全的嗎?如果不安全,要怎麼解決?

  • spring bean 的作用域有五種,分別是 sigleton,prototype,request,session,global session,默認爲 sigleton。作用域爲 sigleton 的時候,它是不安全的,但是交給 spring 管理的 bean 一般都是無狀態的,從這個角度來說也是安全的。如果要變成線程安全的,可以將作用域改爲 prototype,表示每次獲取 bean 都會創建一個新的 bean,也可以用 ThreadLocal 來保證線程安全。

6. 說一說 Spring bean 的生命週期。

  • 實例化,設置屬性,一些列可選的操作,比如執行自定義初始化方法,使用 bean,最後是銷燬。

7. 依賴注入有哪些方式?

  • 構造注入、set方法注入、靜態工廠注入、工廠注入。

8. 自動裝配有哪些方式?@Autowired 和 @Resource 有什麼區別?

  • 默認不自動裝配,byName 是根據 bean 的名稱裝配,byType 是根據 bean 的類型裝配,constructor 是構造注入,autodetect 是先根據構造注入,失敗就根據類型注入。@Autowired 優先根據類型裝配,沒找到或找到多個再根據名稱裝配,@Resource 優先根據名稱裝配,沒找到再根據類型裝配。

9. 說說你對 Spring AOP 的理解。

AOP 就是面向切面編程,把與業務邏輯無關且同時影響多個對象的代碼抽取出來形成切面,降低模塊之間的耦合度,提高了代碼的複用性。AOP 中的核心概念有:

  • 連接點:要做增強的方法;
  • 切點:連接點的集合;
  • 通知:要對方法做的增強,分爲前置通知,後置通知,環繞通知,異常通知和返回通知;
  • 切面:切點加通知就是切面;
  • 目標對象:被切面操作的對象;
  • 織入:將切面應用到目標對象並且創建代理對象的過程。

10. Spring AOP 的原理是什麼?

  • AOP 的原理是動態代理,如果代理的對象實現了接口,用的是 JDK 動態代理,如果沒有實現接口,用的是 cglib 代理,cglib 封裝了 asm,通過修改字節碼文件實現代理。

11. 說一說 Spring 的事務。

Spring 事務是通過對數據庫事務的支持來實現的,分爲編程式事務和聲明式事務,我們常用的是聲明式事務,用註解的方式,對代碼沒有侵入。Spring 事務的傳播行爲有七種:

  • propagation_required:當前存在事務就加入,不存在就創建新事務;
  • propagation_supported:當前存在事務就加入,不存在就以非事務方式運行;
  • propagation_mandatory:當前存在事務就加入,不存在就報異常;
  • propagation_required_new:創建新事物;
  • propagation_not_support:當前存在事務就將事務掛起,然後以非事務方式運行;
  • propagation_never:當前存在事務就報異常,必須以非事務方式運行;
  • propagation_nested:當前存在事務就創建新事務作爲嵌套事務,不存在就創建新事務。

12. 瞭解 SpringMVC 的工作流程嗎?

  • 請求先到前端控制器 DispatcherServlet;
  • DispatcherServlet 請求處理器映射器 HandlerMapping;
  • HandlerMapping 根據請求找到 Handler;
  • 通過 HandlerAdapter 執行 Handler;
  • 執行完返回 ModelAndView 給 DispatcherServlet;
  • DispatcherServlet 請求視圖解析器 ViewResolver;
  • ViewResolver 解析視圖,把 Model 數據渲染到視圖,把 View 返回給用戶。

13. BeanFactory 和 FactoryBean 有什麼區別?

BeanFactory 是 Spring IOC 最底層的基礎組件,管理 bean 的,而 FactoryBean 是用來創建 bean 的,是創建 bean 的一種方式,實現 Factory Bean 重寫其方法可以創建 bean。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章