spring 常見(jiàn)面試題(附答案)
1、什么是spring、為什么要用spring及其優(yōu)點(diǎn)、spring有哪些模塊組成 ?
什么是spring
Spring 是個(gè)Java企業(yè)級(jí)應(yīng)用的開(kāi)源開(kāi)發(fā)框架。Spring主要用來(lái)開(kāi)發(fā)Java應(yīng)用,但是有些擴(kuò)展是針對(duì)構(gòu)建J2EE平臺(tái)的web應(yīng)用。Spring 框架目標(biāo)是簡(jiǎn)化Java企業(yè)級(jí)應(yīng)用開(kāi)發(fā),它使得開(kāi)發(fā)者只需要關(guān)心業(yè)務(wù)需求。
spring優(yōu)點(diǎn)
- spring屬于低侵入式設(shè)計(jì),代碼的污染極低;
- spring的DI機(jī)制將對(duì)象之間的依賴(lài)關(guān)系交由框架處理,減低組件的耦合性;
- Spring提供了AOP技術(shù),支持將一些通用任務(wù),如安全、事務(wù)、日志、權(quán)限等進(jìn)行集中式管理,從而提供更好的復(fù)用。
- spring對(duì)于主流的應(yīng)用框架提供了集成支持。
spring有哪些模塊組成
- Spring Core:核心類(lèi)庫(kù),提供IOC服務(wù);
- Spring Context:提供框架式的Bean訪問(wèn)方式,以及企業(yè)級(jí)功能(JNDI、定時(shí)任務(wù)等);
- Spring AOP:AOP服務(wù);
- Spring DAO:對(duì)JDBC的抽象,簡(jiǎn)化了數(shù)據(jù)訪問(wèn)異常的處理;
- Spring ORM:對(duì)現(xiàn)有的ORM框架的支持;
- Spring Web:提供了基本的面向Web的綜合特性,例如多方文件上傳;
- Spring MVC:提供面向Web應(yīng)用的Model-View-Controller實(shí)現(xiàn)。
2、什么是IOC、DI 及其兩者的優(yōu)點(diǎn) 、 有哪幾種注入方式
IOC:控制反轉(zhuǎn),把創(chuàng)建對(duì)象的控制權(quán)利由代碼轉(zhuǎn)移到spring的配置文件中。
最直觀的表達(dá)就是,IOC讓對(duì)象的創(chuàng)建不用去new了,可以由spring自動(dòng)生產(chǎn),使用java的反射機(jī)制,根據(jù)配置文件在運(yùn)行時(shí)動(dòng)態(tài)的去創(chuàng)建對(duì)象以及管理對(duì)象,并調(diào)用對(duì)象的方法的。
DI:依賴(lài)注入,在程序運(yùn)行期間,由外部容器動(dòng)態(tài)地將依賴(lài)對(duì)象注入到組件中。簡(jiǎn)單定義就是當(dāng)一個(gè)對(duì)象需要另一個(gè)對(duì)象時(shí),可以把另一個(gè)對(duì)象注入到對(duì)象中去。
優(yōu)點(diǎn)就是把應(yīng)用的代碼量降到最低,達(dá)到松散耦合度。
注入的方式:
- 構(gòu)造注入
- Set注入
- 接口注入
Spring提供以下幾種集合的配置元素:
<list>類(lèi)型用于注入一列值,允許有相同的值。
<set> 類(lèi)型用于注入一組值,不允許有相同的值。
<map> 類(lèi)型用于注入一組鍵值對(duì),鍵和值都可以為任意類(lèi)型。
<props>類(lèi)型用于注入一組鍵值對(duì),鍵和值都只能為String類(lèi)型。
3、談?wù)剬?duì)AOP理解?
aop面向切面編程,關(guān)鍵在于代理模式,Spring AOP使用的動(dòng)態(tài)代理,所謂的動(dòng)態(tài)代理就是說(shuō)AOP框架不會(huì)去修改字節(jié)碼,而是每次運(yùn)行時(shí)在內(nèi)存中臨時(shí)為方法生成一個(gè)AOP對(duì)象,這個(gè)AOP對(duì)象包含了目標(biāo)對(duì)象的全部方法,并且在特定的切點(diǎn)做了增強(qiáng)處理,并回調(diào)原對(duì)象的方法。動(dòng)態(tài)代理可以減少系統(tǒng)中的重復(fù)代碼,降低了模塊間的耦合度,同時(shí)提高了系統(tǒng)的可維護(hù)性??捎糜跈?quán)限認(rèn)證、日志、事務(wù)處理。
Spring AOP中的動(dòng)態(tài)代理主要有兩種方式,JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理:
JDK代理:基于接口的代理,不支持類(lèi)的代理。核心InvocationHandler接口和Proxy類(lèi),InvocationHandler 通過(guò)invoke()方法反射來(lái)調(diào)用目標(biāo)類(lèi)中的代碼,動(dòng)態(tài)地將橫切邏輯和業(yè)務(wù)編織在一起;接著,Proxy利用 InvocationHandler動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的的實(shí)例, 生成目標(biāo)類(lèi)的代理對(duì)象。
Proxy.newProxyInstance(ClassLoader,Interfaces,InvocationHandler);
CGLIB動(dòng)態(tài)代理:如果代理類(lèi)沒(méi)有實(shí)現(xiàn) InvocationHandler 接口(或者說(shuō)是基于父子類(lèi)的),那么Spring AOP會(huì)選擇使用CGLIB來(lái)動(dòng)態(tài)代理目標(biāo)類(lèi)。CGLIB(Code Generation Library),是一個(gè)代碼生成的類(lèi)庫(kù),可以在運(yùn)行時(shí)動(dòng)態(tài)的生成指定類(lèi)的一個(gè)子類(lèi)對(duì)象,并覆蓋其中特定方法并添加增強(qiáng)代碼,從而實(shí)現(xiàn)AOP。CGLIB是通過(guò)繼承的方式做的動(dòng)態(tài)代理,因此如果某個(gè)類(lèi)被標(biāo)記為final,那么它是無(wú)法使用CGLIB做動(dòng)態(tài)代理的
Enhancer是一個(gè)非常重要的類(lèi),它允許為非接口類(lèi)型創(chuàng)建一個(gè)JAVA代理,Enhancer動(dòng)態(tài)的創(chuàng)建給定類(lèi)的子類(lèi)并且攔截代理類(lèi)的所有的方法,和JDK動(dòng)態(tài)代理不一樣的是不管是接口還是類(lèi)它都能正常工作

sping的動(dòng)態(tài)代理通過(guò)代理類(lèi)為目標(biāo)對(duì)象增加額外功能。
代理本質(zhì) = 目標(biāo)對(duì)象+額外功能+代理對(duì)象的接口
開(kāi)發(fā)步驟:
1,創(chuàng)建原始對(duì)象
2,提供額外功能(實(shí)現(xiàn)下面的接口)
- MethodBeforeAdvice 額外功能需要運(yùn)行在原始方法之前執(zhí)行.
- AfterReturningAdvice 額外功能需要運(yùn)行在原始方法之后執(zhí)行
- MethodInterceptor 額外功能需要運(yùn)行在原始方法之前 后執(zhí)行
- ThrowsAdvice 額外功能運(yùn)行在原始方法拋出異常的執(zhí)行
3,配置切入點(diǎn)
<aop:pointcut expression="execution(* *(..))"/>
4,組裝切入點(diǎn)和代理功能
<aop:advisor pointcut-ref="pc" advice-ref="代理功能的bean"/>
4、spring事務(wù)的實(shí)現(xiàn)及其原理
Spring事務(wù)的本質(zhì)其實(shí)就是數(shù)據(jù)庫(kù)對(duì)事務(wù)的支持,沒(méi)有數(shù)據(jù)庫(kù)的事務(wù)支持,spring是無(wú)法提供事務(wù)功能的。
(1)Spring事務(wù)的種類(lèi):
spring支持編程式事務(wù)管理和聲明式事務(wù)管理兩種方式:
①編程式事務(wù)管理使用TransactionTemplate。
②聲明式事務(wù)管理建立在AOP之上的。其本質(zhì)是通過(guò)AOP功能,對(duì)方法前后進(jìn)行攔截,將事務(wù)處理的功能編織到攔截的方法中,也就是在目標(biāo)方法開(kāi)始之前加入一個(gè)事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。
聲明式事務(wù)最大的優(yōu)點(diǎn)就是不需要在業(yè)務(wù)邏輯代碼中摻雜事務(wù)管理的代碼,只需在配置文件中做相關(guān)的事務(wù)規(guī)則聲明或通過(guò)@Transactional注解的方式,便可以將事務(wù)規(guī)則應(yīng)用到業(yè)務(wù)邏輯中。
聲明式事務(wù)管理要優(yōu)于編程式事務(wù)管理,這正是spring倡導(dǎo)的非侵入式的開(kāi)發(fā)方式,使業(yè)務(wù)代碼不受污染,只要加上注解就可以獲得完全的事務(wù)支持。唯一不足地方是,最細(xì)粒度只能作用到方法級(jí)別,無(wú)法做到像編程式事務(wù)那樣可以作用到代碼塊級(jí)別。
(2)spring的事務(wù)傳播行為:
spring事務(wù)的傳播行為說(shuō)的是,當(dāng)多個(gè)事務(wù)同時(shí)存在的時(shí)候,spring如何處理這些事務(wù)的行為。
① PROPAGATION_REQUIRED:如果當(dāng)前沒(méi)有事務(wù),就創(chuàng)建一個(gè)新事務(wù),如果當(dāng)前存在事務(wù),就加入該事務(wù),該設(shè)置是最常用的設(shè)置。
② PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前存在事務(wù),就加入該事務(wù),如果當(dāng)前不存在事務(wù),就以非事務(wù)執(zhí)行。‘
③ PROPAGATION_MANDATORY:支持當(dāng)前事務(wù),如果當(dāng)前存在事務(wù),就加入該事務(wù),如果當(dāng)前不存在事務(wù),就拋出異常。
④ PROPAGATION_REQUIRES_NEW:創(chuàng)建新事務(wù),無(wú)論當(dāng)前存不存在事務(wù),都創(chuàng)建新事務(wù)。
⑤ PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。
⑥ PROPAGATION_NEVER:以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。
⑦ PROPAGATION_NESTED:如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒(méi)有事務(wù),則按REQUIRED屬性執(zhí)行。
(3)Spring中的隔離級(jí)別:
① ISOLATION_DEFAULT:這是個(gè) PlatfromTransactionManager 默認(rèn)的隔離級(jí)別,使用數(shù)據(jù)庫(kù)默認(rèn)的事務(wù)隔離級(jí)別。
② ISOLATION_READ_UNCOMMITTED:讀未提交,允許另外一個(gè)事務(wù)可以看到這個(gè)事務(wù)未提交的數(shù)據(jù)。
③ ISOLATION_READ_COMMITTED:讀已提交,保證一個(gè)事務(wù)修改的數(shù)據(jù)提交后才能被另一事務(wù)讀取,而且能看到該事務(wù)對(duì)已有記錄的更新。解決臟讀問(wèn)題
④ ISOLATION_REPEATABLE_READ:可重復(fù)讀,保證一個(gè)事務(wù)修改的數(shù)據(jù)提交后才能被另一事務(wù)讀取,但是不能看到該事務(wù)對(duì)已有記錄的更新。行鎖
⑤ ISOLATION_SERIALIZABLE:一個(gè)事務(wù)在執(zhí)行的過(guò)程中完全看不到其他事務(wù)對(duì)數(shù)據(jù)庫(kù)所做的更新。表鎖
(3)只讀屬性(readOnly)
false應(yīng)用在查詢(xún)操作時(shí),提高查詢(xún)效率, true用于查詢(xún),false用于增刪改,默認(rèn)是false
(4)超時(shí)屬性(timeout) 秒 -1 由數(shù)據(jù)庫(kù)決定
如果當(dāng)前事務(wù)操作的數(shù)據(jù),被別的事務(wù)鎖住,那么通過(guò)超時(shí)數(shù)據(jù)指定最多等待多少秒.
(5)異常屬性(+-Exception)
默認(rèn)Spring會(huì)對(duì)RuntimeException及其子類(lèi)進(jìn)行回滾操作
默認(rèn)Spring會(huì)對(duì)Exception及其子類(lèi)進(jìn)行提交操作
rollback-for=”異常的權(quán)限定名” 回滾操作
no-rollback-for=”java.lang.RuntimeException” 提交操作
簡(jiǎn)單展示

5、Spring有幾種配置方式?
將Spring配置到應(yīng)用開(kāi)發(fā)中有以下三種方式:
基于XML的配置
基于注解的配置(主流)
基于Java的配置
6、Spring 框架中都用到了哪些設(shè)計(jì)模式?
- 工廠模式:BeanFactory就是簡(jiǎn)單工廠模式的體現(xiàn),用來(lái)創(chuàng)建對(duì)象的實(shí)例;
- 單例模式:Bean默認(rèn)為單例模式。
- 代理模式:Spring的AOP功能用到了JDK的動(dòng)態(tài)代理和CGLIB字節(jié)碼生成技術(shù);
- 模板方法:用來(lái)解決代碼重復(fù)的問(wèn)題。比如. RestTemplate, JmsTemplate, JpaTemplate。
- 觀察者模式:定義對(duì)象鍵一種一對(duì)多的依賴(lài)關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都會(huì)得到通知被制動(dòng)更新,如Spring中l(wèi)istener的實(shí)現(xiàn)--ApplicationListener。
7、Spring的自動(dòng)裝配:
在spring中,對(duì)象無(wú)需自己查找或創(chuàng)建與其關(guān)聯(lián)的其他對(duì)象,由容器負(fù)責(zé)把需要相互協(xié)作的對(duì)象引用賦予各個(gè)對(duì)象,使用autowire來(lái)配置自動(dòng)裝載模式。
在Spring框架xml配置中共有5種自動(dòng)裝配:
(1)no:默認(rèn)的方式是不進(jìn)行自動(dòng)裝配的,通過(guò)手工設(shè)置ref屬性來(lái)進(jìn)行裝配bean。
(2)byName:通過(guò)bean的名稱(chēng)進(jìn)行自動(dòng)裝配,如果一個(gè)bean的 property 與另一bean 的name 相同,就進(jìn)行自動(dòng)裝配。
(3)byType:通過(guò)參數(shù)的數(shù)據(jù)類(lèi)型進(jìn)行自動(dòng)裝配。
(4)constructor:利用構(gòu)造函數(shù)進(jìn)行裝配,并且構(gòu)造函數(shù)的參數(shù)通過(guò)byType進(jìn)行裝配。
(5)autodetect:自動(dòng)探測(cè),如果有構(gòu)造方法,通過(guò) construct的方式自動(dòng)裝配,否則使用 byType的方式自動(dòng)裝配。
基于注解的方式:
使用@Autowired注解來(lái)自動(dòng)裝配指定的bean。在使用@Autowired注解之前需要在Spring配置文件進(jìn)行配置,<context:annotation-config />。在啟動(dòng)spring IoC時(shí),容器自動(dòng)裝載了一個(gè)AutowiredAnnotationBeanPostProcessor后置處理器,當(dāng)容器掃描到@Autowied、@Resource或@Inject時(shí),就會(huì)在IoC容器自動(dòng)查找需要的bean,并裝配給該對(duì)象的屬性。在使用@Autowired時(shí),首先在容器中查詢(xún)對(duì)應(yīng)類(lèi)型的bean:
如果查詢(xún)結(jié)果剛好為一個(gè),就將該bean裝配給@Autowired指定的數(shù)據(jù);
如果查詢(xún)的結(jié)果不止一個(gè),那么@Autowired會(huì)根據(jù)名稱(chēng)來(lái)查找;
如果上述查找的結(jié)果為空,那么會(huì)拋出異常。解決方法時(shí),使用required=false。
@Autowired可用于:構(gòu)造函數(shù)、成員變量、Setter方法
注:@Autowired和@Resource之間的區(qū)別
(1) @Autowired默認(rèn)是按照類(lèi)型裝配注入的,默認(rèn)情況下它要求依賴(lài)對(duì)象必須存在(可以設(shè)置它required屬性為false)。
(2) @Resource默認(rèn)是按照名稱(chēng)來(lái)裝配注入的,只有當(dāng)找不到與名稱(chēng)匹配的bean才會(huì)按照類(lèi)型來(lái)裝配注入。
8、Spring如何處理線程并發(fā)問(wèn)題?
在一般情況下,只有無(wú)狀態(tài)的Bean才可以在多線程環(huán)境下共享,在Spring中,絕大部分Bean都可以聲明為singleton作用域,因?yàn)镾pring對(duì)一些Bean中非線程安全狀態(tài)采用ThreadLocal進(jìn)行處理,解決線程安全問(wèn)題。
ThreadLocal和線程同步機(jī)制都是為了解決多線程中相同變量的訪問(wèn)沖突問(wèn)題。同步機(jī)制采用了“時(shí)間換空間”的方式,僅提供一份變量,不同的線程在訪問(wèn)前需要獲取鎖,沒(méi)獲得鎖的線程則需要排隊(duì)。而ThreadLocal采用了“空間換時(shí)間”的方式。
ThreadLocal會(huì)為每一個(gè)線程提供一個(gè)獨(dú)立的變量副本,從而隔離了多個(gè)線程對(duì)數(shù)據(jù)的訪問(wèn)沖突。因?yàn)槊恳粋€(gè)線程都擁有自己的變量副本,從而也就沒(méi)有必要對(duì)該變量進(jìn)行同步了。ThreadLocal提供了線程安全的共享對(duì)象,在編寫(xiě)多線程代碼時(shí),可以把不安全的變量封裝進(jìn)ThreadLocal。
9、解釋Spring支持的幾種bean的作用域。
Spring容器中的bean可以分為5個(gè)范圍:
(1)singleton:默認(rèn),每個(gè)容器中只有一個(gè)bean的實(shí)例,單例的模式由BeanFactory自身來(lái)維護(hù)。
(2)prototype:為每一個(gè)bean請(qǐng)求提供一個(gè)實(shí)例。
(3)request:為每一個(gè)網(wǎng)絡(luò)請(qǐng)求創(chuàng)建一個(gè)實(shí)例,在請(qǐng)求完成以后,bean會(huì)失效并被垃圾回收器回收。
(4)session:與request范圍類(lèi)似,確保每個(gè)session中有一個(gè)bean的實(shí)例,在session過(guò)期后,bean會(huì)隨之失效。
(5)global-session:全局作用域,global-session和Portlet應(yīng)用相關(guān)。當(dāng)你的應(yīng)用部署在Portlet容器中工作時(shí),它包含很多portlet。如果你想要聲明讓所有的portlet共用全局的存儲(chǔ)變量的話,那么這全局變量需要存儲(chǔ)在global-session中。全局作用域與Servlet中的session作用域效果相同。
10、怎樣開(kāi)啟注解裝配?
注解裝配在默認(rèn)情況下是不開(kāi)啟的,為了使用注解裝配,我們必須在Spring配置文件中配置 <context:annotation-config/>元素。
11、spring核心類(lèi)有哪些?各有什么作用?
BeanFactory:產(chǎn)生一個(gè)新的實(shí)例,可以實(shí)現(xiàn)單例模式
BeanWrapper:提供統(tǒng)一的get及set方法
ApplicationContext:提供框架的實(shí)現(xiàn),包括BeanFactory的所有功能
12、Spring框架中的單例bean是線程安全的嗎?
不,Spring框架中的單例bean不是線程安全的。
到此這篇關(guān)于spring 常見(jiàn)面試題(附答案)的文章就介紹到這了,更多相關(guān)spring面試題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章

Spring面試題50道,應(yīng)該至少答對(duì)30個(gè)(附答案)
這篇文章主要介紹了Spring面試題50道,應(yīng)該至少答對(duì)30個(gè)(附答案),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編2020-06-16
SpringMVC常見(jiàn)面試題總結(jié)(超詳細(xì)回答)
這篇文章主要介紹了SpringMVC常見(jiàn)面試題總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-05-27
一文帶你輕松應(yīng)對(duì)Springboot面試小結(jié)
這篇文章主要介紹了一文帶你輕松應(yīng)對(duì)Springboot面試小結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-05-12
這篇文章主要介紹了2020最新版Spring Cloud面試題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-03-17
這篇文章主要介紹了2020最新版Spring面試題 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-03-172019 最新「Spring 全家桶」高頻面試題(小結(jié))
這篇文章主要介紹了2019 最新「Spring 全家桶」高頻面試題(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-08-2627道高頻Spring面試題,你能答對(duì)幾個(gè)?
這篇文章主要介紹了27道高頻Spring面試題,你能答對(duì)幾個(gè)?小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-08-08Java研發(fā)面試99題(含答案):JVM+Spring+MySQL+線程池+鎖
這篇文章主要介紹了Java研發(fā)面試99題,主要包括了JVM,Spring,MySQL,線程池,鎖等,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-07-16
這篇文章主要介紹了35道SpringBoot面試題及答案(小結(jié))的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-21
49個(gè)Spring經(jīng)典面試題總結(jié)(附帶答案)
這篇文章主要介紹了49個(gè)Spring經(jīng)典面試題總結(jié)(附帶答案)的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-29








