1. Spring 有哪些特點?
- 輕量級:不管是 spring 的代碼量還是運行所需要的開銷,都算是輕量級的;
- 控制反轉(zhuǎn):控制反轉(zhuǎn)就是創(chuàng)建對象的權(quán)利轉(zhuǎn)交給 spring,程序要用的時候注入就行,降低了耦合度;
- 面向切面:將與業(yè)務(wù)無關(guān)卻影響多個對象的代碼抽取出來,形成切面。
2. Spring 的核心模塊有哪些? Spring 有七大核心模塊: - Spring core:核心模塊,提供 Spring 的基礎(chǔ)功能;
- Spring Aop:提供了對面向切面編程的支持;
- Spring Context:應(yīng)用上下文模塊,向 Spring 框架提供上下文信息;
- Spring Dao:提供了數(shù)據(jù)庫操作的基礎(chǔ)結(jié)構(gòu);
- Spring Web:提供了對 web 開發(fā)的支持,基于 web 程序提供上下文;
- Spring Web MVC:構(gòu)建 web 應(yīng)用程序的 MVC 實現(xiàn)。
3. 什么是 Spring ioc?
- IOC 就是控制反轉(zhuǎn),創(chuàng)建對象的權(quán)力交給 Spring,要用的時候直接從 IOC 容器中取出即可。它最核心的就是refresh方法,其包含了13個核心方法,大體流程是:首先會判斷當前有沒有 beanFactory 容器,如果沒有,就創(chuàng)建 beanFactory 容器,然后通過 BeanDefinitionReader 對象讀取配置文件或者注解,將配置都封裝成 BeanDifinition 對象,再通過 BeanFactoryPostProcessor 來完成對 beanFactory 信息的修改或者擴展。然后會準備好 beanPostProcessor,監(jiān)聽器,廣播器等,之后通過反射執(zhí)行實例化操作,接著是進行 bean 的初始化,包括用 populateBean 方法填充屬性,執(zhí)行 aware 接口的方法,給 bean 設(shè)置所需要的容器內(nèi)置的bean;接著執(zhí)行 beanPostProcessor 來完成對 bean 的修改或者擴展,最后生成一個完整對象。AOP 功能就是通過 BeanPostProcessor 來實現(xiàn)的。
4. 說一說循環(huán)依賴怎么解決。 -循環(huán)依賴就是 A 對象有屬性 b,B 對象有屬性 A,這就是循環(huán)依賴。假如通過構(gòu)造方法創(chuàng)建對象,創(chuàng)建 A 的時候要傳入 B,B 又還沒有,就得創(chuàng)建,創(chuàng)建 B 又得傳入 A,這樣就會無限套娃,所以 Spring 只能解決 setter 注入的循環(huán)依賴問題。它是用三級緩存解決的,其實也就是三個 map,一級緩存保存的是成品對象;二級緩存保存的是半成品對象,即實例化了但是屬性還沒賦值的對象;三級緩存保存的是 lambda 表達式。解決三級緩存的流程為:創(chuàng)建 A 對象之前,就會判斷緩存中有沒有 A,如果沒有,就會創(chuàng)建 A 對象,在給 A 對象屬性賦值之前,就會調(diào)用 addSingletonFactory 方法,該方法傳入一個 lambda 表達式,與此同時會把這個 lambda 表達式放進三級緩存中;接著填充屬性,發(fā)現(xiàn)屬性 b 為空,就會實例化 B,實例化 B 和實例化 A 流程一樣,在給 b 填充屬性的時候,發(fā)現(xiàn) a 為空,但是三級緩存中有 a 對象的 lambda 表達式,然后就會執(zhí)行這段表達式,就得到了 a 對象,半成品 a 對象就會放到二級緩存中。賦值完的 b 對象,就是一個成品對象了,就會放到一級緩存中,回去再給 a 對象的 b 屬性賦值時,就直接從一級緩存中取出 b 對象,賦值完的 a 對象也是一個成品對象了,也會放到一級緩存中。如果沒有用到 aop,則用兩級緩存,也可以解決循環(huán)依賴問題,如果用到了 aop,必須要三級,因為兩級緩存無法區(qū)分對象的版本。
5. Spring bean 是安全的嗎?如果不安全,要怎么解決?
- spring bean 的作用域有五種,分別是 sigleton,prototype,request,session,global session,默認為 sigleton。作用域為 sigleton 的時候,它是不安全的,但是交給 spring 管理的 bean 一般都是無狀態(tài)的,從這個角度來說也是安全的。如果要變成線程安全的,可以將作用域改為 prototype,表示每次獲取 bean 都會創(chuàng)建一個新的 bean,也可以用 ThreadLocal 來保證線程安全。
6. 說一說 Spring bean 的生命周期。
- 實例化,設(shè)置屬性,一些列可選的操作,比如執(zhí)行自定義初始化方法,使用 bean,最后是銷毀。
7. 依賴注入有哪些方式?
- 構(gòu)造注入、set方法注入、靜態(tài)工廠注入、工廠注入。
8. 自動裝配有哪些方式?@Autowired 和 @Resource 有什么區(qū)別?
- 默認不自動裝配,byName 是根據(jù) bean 的名稱裝配,byType 是根據(jù) bean 的類型裝配,constructor 是構(gòu)造注入,autodetect 是先根據(jù)構(gòu)造注入,失敗就根據(jù)類型注入。@Autowired 優(yōu)先根據(jù)類型裝配,沒找到或找到多個再根據(jù)名稱裝配,@Resource 優(yōu)先根據(jù)名稱裝配,沒找到再根據(jù)類型裝配。
9. 說說你對 Spring AOP 的理解。 AOP 就是面向切面編程,把與業(yè)務(wù)邏輯無關(guān)且同時影響多個對象的代碼抽取出來形成切面,降低模塊之間的耦合度,提高了代碼的復用性。AOP 中的核心概念有: - 通知:要對方法做的增強,分為前置通知,后置通知,環(huán)繞通知,異常通知和返回通知;
- 織入:將切面應(yīng)用到目標對象并且創(chuàng)建代理對象的過程。
10. Spring AOP 的原理是什么?
- AOP 的原理是動態(tài)代理,如果代理的對象實現(xiàn)了接口,用的是 JDK 動態(tài)代理,如果沒有實現(xiàn)接口,用的是 cglib 代理,cglib 封裝了 asm,通過修改字節(jié)碼文件實現(xiàn)代理。
11. 說一說 Spring 的事務(wù)。 Spring 事務(wù)是通過對數(shù)據(jù)庫事務(wù)的支持來實現(xiàn)的,分為編程式事務(wù)和聲明式事務(wù),我們常用的是聲明式事務(wù),用注解的方式,對代碼沒有侵入。Spring 事務(wù)的傳播行為有七種: - propagation_required:當前存在事務(wù)就加入,不存在就創(chuàng)建新事務(wù);
- propagation_supported:當前存在事務(wù)就加入,不存在就以非事務(wù)方式運行;
- propagation_mandatory:當前存在事務(wù)就加入,不存在就報異常;
- propagation_required_new:創(chuàng)建新事物;
- propagation_not_support:當前存在事務(wù)就將事務(wù)掛起,然后以非事務(wù)方式運行;
- propagation_never:當前存在事務(wù)就報異常,必須以非事務(wù)方式運行;
- propagation_nested:當前存在事務(wù)就創(chuàng)建新事務(wù)作為嵌套事務(wù),不存在就創(chuàng)建新事務(wù)。
12. 了解 SpringMVC 的工作流程嗎?
- 請求先到前端控制器 DispatcherServlet;
- DispatcherServlet 請求處理器映射器 HandlerMapping;
- HandlerMapping 根據(jù)請求找到 Handler;
- 通過 HandlerAdapter 執(zhí)行 Handler;
- 執(zhí)行完返回 ModelAndView 給 DispatcherServlet;
- DispatcherServlet 請求視圖解析器 ViewResolver;
- ViewResolver 解析視圖,把 Model 數(shù)據(jù)渲染到視圖,把 View 返回給用戶。
13. BeanFactory 和 FactoryBean 有什么區(qū)別? BeanFactory 是 Spring IOC 最底層的基礎(chǔ)組件,管理 bean 的,而 FactoryBean 是用來創(chuàng)建 bean 的,是創(chuàng)建 bean 的一種方式,實現(xiàn) Factory Bean 重寫其方法可以創(chuàng)建 bean。
|