Java面試題沖刺第七天--Spring框架1
面試題1:能簡(jiǎn)單說一下你對(duì)Spring框架的理解么?
我們一般說的Spring框架就是Spring Framework,一種輕量級(jí)框架,用于提高開發(fā)人員的開發(fā)效率和可維護(hù)性。它是很多模塊的集合,使用這些模塊可以很方便地協(xié)助我們進(jìn)行開發(fā)。這些模塊包括:核心容器
、數(shù)據(jù)訪問/集成
、響應(yīng)式 web 編程
、AOP(面向切面編程)
、工具
、消息和測(cè)試模塊
。
下圖對(duì)應(yīng)的是Spring 4.x的版本,目前最新的5.x版本中Web模塊的Portlet組件已經(jīng)被廢棄掉,同時(shí)增加了用于異步響應(yīng)式處理的WebFlux組件。
主要模塊包括:
Spring Core
:Core封裝包是框架的最基礎(chǔ)部分,提供IOC和依賴注入特性
。這里的基礎(chǔ)概念是BeanFactory,它提供對(duì)Factory模式的經(jīng)典實(shí)現(xiàn)來消除對(duì)程序性單例模式的需要,并真正地允許你從程序邏輯中分離出依賴關(guān)系和配置。
Spring AOP
:AOP模塊是Spring的AOP庫(kù),提供了AOP(攔截器)機(jī)制
,并提供常用的攔截器,供用戶自定義和配置。
Spring JDBC
:負(fù)責(zé)Java數(shù)據(jù)庫(kù)連接。
Spring JMS
:負(fù)責(zé)Java消息服務(wù)。
Spring ORM
:用于支持常用的Hibernate,Mybatis等框架,Spring本身并不對(duì)ORM進(jìn)行實(shí)現(xiàn),僅對(duì)常見的ORM框架進(jìn)行封裝
,并對(duì)其進(jìn)行管理;
Spring Web
:WEB模塊提供對(duì)常見框架如Struts X,SpringMVC,JSF的支持,Spring能夠管理這些框架,將Spring的資源注入給框架,也能在這些框架的前后插入攔截器。
Spring Test
:提供了對(duì)JUnit和TestNG測(cè)試的支持。
Core Container中的
Core
組件是Spring所有組件的核心,Beans
組件和Context
組件是實(shí)現(xiàn)IOC和DI的基礎(chǔ),AOP
組件用來實(shí)現(xiàn)面向切面編程。
追問1:常見的Core組件有哪些?
- IoC Container,控制反轉(zhuǎn)容器
- Events,事件編程
- Resources,資源加載
- i18n,國(guó)際化
- Validation,校驗(yàn)
- Data Binding,數(shù)據(jù)綁定
- Type Conversion,類型轉(zhuǎn)換
- SpEL,Spring 表達(dá)式
- AOP,面向切面編程
面試題2:談?wù)剬?duì)Spring IOC的理解
IOC(Inversion Of Controll
,控制反轉(zhuǎn))是一種設(shè)計(jì)思想,就是將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán),交由給Spring框架來管理。
IOC在其他語言中也有應(yīng)用,并非Spring特有。IOC容器是Spring用來實(shí)現(xiàn)IOC的載體,IOC容器實(shí)際上就是一個(gè)Map(key, value)
,Map中存放的是各種對(duì)象。
將對(duì)象之間的相互依賴關(guān)系交給IOC容器來管理,并由IOC容器完成對(duì)象的注入。這樣可以很大程度上簡(jiǎn)化應(yīng)用的開發(fā),把應(yīng)用從復(fù)雜的依賴關(guān)系中解放出來。IOC容器就像是一個(gè)工廠一樣,當(dāng)我們需要?jiǎng)?chuàng)建一個(gè)對(duì)象的時(shí)候,只需要配置好配置文件/注解即可,完全不用考慮對(duì)象是如何被創(chuàng)建出來的
。在實(shí)際項(xiàng)目中一個(gè)Service類可能由幾百甚至上千個(gè)類作為它的底層,假如我們需要實(shí)例化這個(gè)Service,可能要每次都搞清楚這個(gè)Service所有底層類的構(gòu)造函數(shù),這是不現(xiàn)實(shí)的。如果利用IOC的話,你只需要配置好,然后在需要的地方引用就行了
,大大增加了項(xiàng)目的可維護(hù)性且降低了開發(fā)難度。
Spring時(shí)代我們一般通過XML文件來配置Bean,后來開發(fā)人員覺得用XML文件來配置不太友好,于是Sprng Boot注解配置就慢慢開始流行起來。
追問1:Spring中的bean的作用域有哪些?
spring 支持 5 種作用域,如下:
singleton
:唯一bean實(shí)例,Spring中的bean默認(rèn)都是單例的。prototype
:每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的bean實(shí)例。request
:每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean,該bean僅在當(dāng)前HTTP request內(nèi)有效。session
:每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean,該bean僅在當(dāng)前HTTP session內(nèi)有效。global-session
:全局session作用域,僅僅在基于Portlet的Web應(yīng)用中才有意義,Spring5中已經(jīng)沒有了。Portlet是能夠生成語義代碼(例如HTML)片段的小型Java Web插件。它們基于Portlet容器,可以像Servlet一樣處理HTTP請(qǐng)求。但是與Servlet不同,每個(gè)Portlet都有不同的會(huì)話。
追問2:Spring中的bean生命周期?
- Bean容器找到配置文件中Spring Bean的定義。
- Bean容器利用Java Reflection API創(chuàng)建一個(gè)Bean的實(shí)例。
- 如果涉及到一些屬性值,利用set()方法設(shè)置一些屬性值。
- 如果Bean實(shí)現(xiàn)了BeanNameAware接口,調(diào)用setBeanName()方法,傳入Bean的名字。
- 如果Bean實(shí)現(xiàn)了BeanClassLoaderAware接口,調(diào)用
setBeanClassLoader()
方法,傳入ClassLoader對(duì)象的實(shí)例。 - 如果Bean實(shí)現(xiàn)了BeanFactoryAware接口,調(diào)用
setBeanClassFacotory()
方法,傳入ClassLoader對(duì)象的實(shí)例。 - 與上面的類似,如果實(shí)現(xiàn)了其他*Aware接口,就調(diào)用相應(yīng)的方法。
- 如果有和加載這個(gè)Bean的Spring容器相關(guān)的BeanPostProcessor對(duì)象,執(zhí)行
postProcessBeforeInitialization()
方法。 - 如果Bean實(shí)現(xiàn)了InitializingBean接口,執(zhí)行
afeterPropertiesSet()
方法。 - 如果Bean在配置文件中的定義包含init-method屬性,執(zhí)行指定的方法。
- 如果有和加載這個(gè)Bean的Spring容器相關(guān)的BeanPostProcess對(duì)象,執(zhí)行postProcessAfterInitialization()方法。
- 當(dāng)要銷毀Bean的時(shí)候,如果Bean實(shí)現(xiàn)了DisposableBean接口,執(zhí)行destroy()方法。
- 當(dāng)要銷毀Bean的時(shí)候,如果Bean在配置文件中的定義包含destroy-method屬性,
執(zhí)行指定的方法
。
追問3: Spring 中的 bean 是線程安全的嗎?
Spring容器中的Bean是否線程安全,容器本身并沒有提供Bean的線程安全策略
,因此可以說Spring容器中的Bean本身不具備線程安全的特性
,但是具體還是要結(jié)合具體scope的Bean去研究。
結(jié)合上面提到的Spring bean 的作用域(scope)
1.對(duì)于prototype作用域的Bean
,每次都創(chuàng)建一個(gè)新對(duì)象,也就是線程之間不存在Bean共享,因此不會(huì)有線程安全問題。
2.對(duì)于singleton作用域的Bean
,所有的線程都共享一個(gè)單例實(shí)例的Bean,因此是存在線程安全問題的。但是如果單例Bean是一個(gè)無狀態(tài)Bean,也就是線程中的操作不會(huì)對(duì)Bean的成員執(zhí)行查詢以外的操作,那么這個(gè)單例Bean是線程安全的。比如Controller類、Service類和Dao等,這些Bean大多是無狀態(tài)的,只關(guān)注于方法本身。
有狀態(tài)Bean
(Stateful Bean) :就是有實(shí)例變量的對(duì)象,可以保存數(shù)據(jù),是非線程安全的
。
無狀態(tài)Bean
(Stateless Bean):就是沒有實(shí)例變量的對(duì)象,不能保存數(shù)據(jù),是不變類,是線程安全的。
線程安全這個(gè)問題,要從單例與原型Bean分別進(jìn)行說明。
對(duì)于有狀態(tài)的bean
(比如ModelAndView),就需要自行保證線程安全,最淺顯的解決辦法就是將有狀態(tài)的bean的作用域由“singleton”改為“prototype
”。也可以采用ThreadLocal
解決線程安全問題,為每個(gè)線程提供一個(gè)獨(dú)立的變量副本,不同線程只操作自己線程的副本變量。
ThreadLocal和線程同步機(jī)制都是為了解決多線程中相同變量的訪問沖突問題。
同步機(jī)制
:采用了“時(shí)間換空間”的方式,僅提供一份變量,不同的線程在訪問前需要獲取鎖,沒獲得鎖的線程則需要排隊(duì)。ThreadLocal
:采用了“空間換時(shí)間”的方式。ThreadLocal會(huì)為每一個(gè)線程提供一個(gè)獨(dú)立的變量副本,從而隔離了多個(gè)線程對(duì)數(shù)據(jù)的訪問沖突。因?yàn)槊恳粋€(gè)線程都擁有自己的變量副本,從而也就沒有必要對(duì)該變量進(jìn)行同步了。
面試題3:說一下 SpringMVC 運(yùn)行流程?
流程說明:
- 客戶端(瀏覽器)發(fā)送請(qǐng)求,直接請(qǐng)求到DispatcherServlet。
DispatcherServlet根據(jù)請(qǐng)求信息調(diào)用HandlerMapping,解析請(qǐng)求對(duì)應(yīng)的Handler。
- 解析到對(duì)應(yīng)的
Handler
(也就是我們平常說的Controller控制器
)。 - HandlerAdapter會(huì)根據(jù)Handler來調(diào)用真正的處理器(
對(duì)應(yīng)的接口
)來處理請(qǐng)求和執(zhí)行相對(duì)應(yīng)的業(yè)務(wù)邏輯。 - 處理器處理完業(yè)務(wù)后,會(huì)返回一個(gè)ModelAndView對(duì)象,Model是返回的數(shù)據(jù)對(duì)象,View是邏輯上的View。
- ViewResolver(視圖解析器)會(huì)根據(jù)邏輯View去查找實(shí)際的View。
- DispatcherServlet把返回的Model傳給View(視圖渲染)。
- 把View返回給請(qǐng)求者(瀏覽器)。
追問1:能介紹一下SpringMVC各組件的作用么?
DispatcherServlet
:前端控制器
。用戶請(qǐng)求到達(dá)前端控制器,它就相當(dāng)于mvc模式中的c,dispatcherServlet是整個(gè)流程控制的中心,由它調(diào)用其它組件處理用戶的請(qǐng)求,dispatcherServlet的存在降低了組件之間的耦合性,系統(tǒng)擴(kuò)展性提高。由框架實(shí)現(xiàn)HandlerMapping
:處理器映射器
。HandlerMapping負(fù)責(zé)根據(jù)用戶請(qǐng)求的url找到Handler即處理器,springmvc提供了不同的映射器實(shí)現(xiàn)不同的映射方式,根據(jù)一定的規(guī)則去查找,例如:xml配置方式,實(shí)現(xiàn)接口方式,注解方式等。由框架實(shí)現(xiàn)Handler
:處理器
。Handler 是繼DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler對(duì)具體的用戶請(qǐng)求進(jìn)行處理。由于Handler涉及到具體的用戶業(yè)務(wù)請(qǐng)求,所以一般情況需要程序員根據(jù)業(yè)務(wù)需求開發(fā)Handler。HandlAdapter
:處理器適配器
。通過HandlerAdapter對(duì)處理器進(jìn)行執(zhí)行,這是適配器模式的應(yīng)用,通過擴(kuò)展適配器可以對(duì)更多類型的處理器進(jìn)行執(zhí)行。由框架實(shí)現(xiàn)。ModelAndView
:是springmvc的封裝對(duì)象,將model和view封裝在一起
。ViewResolver
:視圖解析器
。ViewResolver負(fù)責(zé)將處理結(jié)果生成View視圖,ViewResolver首先根據(jù)邏輯視圖名解析成物理視圖名即具體的頁(yè)面地址,再生成View視圖對(duì)象,最后對(duì)View進(jìn)行渲染將處理結(jié)果通過頁(yè)面展示給用戶。View
:是springmvc的封裝對(duì)象,是一個(gè)接口, springmvc框架提供了很多的View視圖類型,包括:jspview,pdfview,jstlView、freemarkerView、pdfView等。一般情況下需要通過頁(yè)面標(biāo)簽或頁(yè)面模版技術(shù)將模型數(shù)據(jù)通過頁(yè)面展示給用戶,需要由程序員根據(jù)業(yè)務(wù)需求開發(fā)具體的頁(yè)面。
總結(jié)
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
簡(jiǎn)單講解Java設(shè)計(jì)模式編程中的單一職責(zé)原則
這篇文章主要介紹了Java設(shè)計(jì)模式編程中的單一職責(zé)原則,這在團(tuán)隊(duì)開發(fā)編寫接口時(shí)經(jīng)常使用這樣的約定,需要的朋友可以參考下2016-02-02Java的MyBatis+Spring框架中使用數(shù)據(jù)訪問對(duì)象DAO模式的方法
Data Access Object數(shù)據(jù)訪問對(duì)象模式在Java操作數(shù)據(jù)庫(kù)部分的程序設(shè)計(jì)中經(jīng)常被使用到,這里我們就來看一下Java的MyBatis+Spring框架中使用數(shù)據(jù)訪問對(duì)象DAO模式的方法:2016-06-06淺談Java讀寫注冊(cè)表的方式Preferences與jRegistry
這篇文章主要介紹了淺談Java讀寫注冊(cè)表的方式Preferences與jRegistry,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02mybatis-plus?查詢傳入?yún)?shù)Map,返回List<Map>方式
這篇文章主要介紹了mybatis-plus?查詢傳入?yún)?shù)Map,返回List<Map>方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12SpringBoot全局異常處理之多個(gè)處理器匹配順序(最新推薦)
這篇文章主要介紹了SpringBoot全局異常處理之多個(gè)處理器匹配順序(最新推薦),調(diào)試源碼可見匹配順序?yàn)椋寒惓蛹?jí)高者優(yōu)先,再清楚點(diǎn),子類異常處理器優(yōu)先,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-03-03什么情況下會(huì)出現(xiàn)java.io.IOException?:?Broken?pipe這個(gè)錯(cuò)誤以及解決辦法
這篇文章主要介紹了什么情況下會(huì)出現(xiàn)java.io.IOException?:?Broken?pipe這個(gè)錯(cuò)誤以及解決辦法的相關(guān)資料,這個(gè)錯(cuò)誤表示通信另一端已關(guān)閉連接,常發(fā)生在客戶端關(guān)閉連接、網(wǎng)絡(luò)超時(shí)或資源不足等情況,文中將解決辦法介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10Java 如何快速實(shí)現(xiàn)一個(gè)連接池
有沒有一個(gè)通用的庫(kù)可以快速實(shí)現(xiàn)一個(gè)線程池呢?得益于 Java 完善的生態(tài),前人們針對(duì)這種需要開發(fā)了一個(gè)通用庫(kù):Apache Commons Pool(下文簡(jiǎn)稱 ACP)。本質(zhì)上來說,ACP 庫(kù)提供的是管理對(duì)象池的通用能力,當(dāng)然也可以用來管理連接池了!2021-05-05springmvc實(shí)現(xiàn)跨服務(wù)器文件上傳功能
這篇文章主要為大家詳細(xì)介紹了springmvc實(shí)現(xiàn)跨服務(wù)器文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08Java8生成時(shí)間方式及格式化時(shí)間的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Java8生成時(shí)間方式及格式化時(shí)間的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08