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