你當前所在位置:首頁 > IT就業問題 > Java面試題及答案(10/19)——Spring / Spring MVC

Java面試題及答案(10/19)——Spring / Spring MVC

90. 為什么要使用 spring?

 

1.簡介

 

 目的:解決企業應用開發的復雜性

 

 功能:使用基本的JavaBean代替EJB,并提供了更多的企業應用功能

 

 范圍:任何Java應用

 

簡單來說,Spring是一個輕量級的控制反轉(IoC)和面向切面(AOP)的容器框架。

 

2.輕量 

 

從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架可以在一個大小只有1MB多的JAR文件里發布。并且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴于Spring的特定類。

 

3.控制反轉  

 

Spring通過一種稱作控制反轉(IoC)的技術促進了松耦合。當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象。你可以認為IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。

 

4.面向切面  

 

Spring提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們并不負責(甚至是意識)其它的系統級關注點,例如日志或事務支持。

 

5.容器

 

Spring包含并管理應用對象的配置和生命周期,在這個意義上它是一種容器,你可以配置你的每個bean如何被創建——基于一個可配置原型(prototype),你的bean可以創建一個單獨的實例或者每次需要時都生成一個新的實例——以及它們是如何相互關聯的。然而,Spring不應該被混同于傳統的重量級的EJB容器,它們經常是龐大與笨重的,難以使用。

 

6.框架

 

Spring可以將簡單的組件配置、組合成為復雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件里。Spring也提供了很多基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。

 

所有Spring的這些特征使你能夠編寫更干凈、更可管理、并且更易于測試的代碼。它們也為Spring中的各種模塊提供了基礎支持。

 

91. 解釋一下什么是 aop?

 

AOP(Aspect-Oriented Programming,面向方面編程),可以說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP引入封裝、繼承和多態性等概念來建立一種對象層次結構,用以模擬公共行為的一個集合。當我們需要為分散的對象引入公共行為的時候,OOP則顯得無能為力。也就是說,OOP允許你定義從上到下的關系,但并不適合定義從左到右的關系。例如日志功能。日志代碼往往水平地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關系。對于其他類型的代碼,如安全性、異常處理和透明的持續性也是如此。這種散布在各處的無關的代碼被稱為橫切(cross-cutting)代碼,在OOP設計中,它導致了大量代碼的重復,而不利于各個模塊的重用。

 

而AOP技術則恰恰相反,它利用一種稱為“橫切”的技術,剖解開封裝的對象內部,并將那些影響了多個類的公共行為封裝到一個可重用模塊,并將其名為“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便于減少系統的重復代碼,降低模塊間的耦合度,并有利于未來的可操作性和可維護性。AOP代表的是一個橫向的關系,如果說“對象”是一個空心的圓柱體,其中封裝的是對象的屬性和行為;那么面向方面編程的方法,就仿佛一把利刃,將這些空心圓柱體剖開,以獲得其內部的消息。而剖開的切面,也就是所謂的“方面”了。然后它又以巧奪天功的妙手將這些剖開的切面復原,不留痕跡。

 

使用“橫切”技術,AOP把軟件系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關系不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處都基本相似。比如權限認證、日志、事務處理。Aop 的作用在于分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。正如Avanade公司的高級方案構架師Adam Magee所說,AOP的核心思想就是“將應用程序中的商業邏輯同對其提供支持的通用服務進行分離。”

 

92. 解釋一下什么是 ioc?

 

IOC是Inversion of Control的縮寫,多數書籍翻譯成“控制反轉”。

 

1996年,Michael Mattson在一篇有關探討面向對象框架的文章中,首先提出了IOC 這個概念。對于面向對象設計及編程的基本思想,前面我們已經講了很多了,不再贅述,簡單來說就是把復雜系統分解成相互合作的對象,這些對象類通過封裝以后,內部實現對外部是透明的,從而降低了解決問題的復雜度,而且可以靈活地被重用和擴展。

 

IOC理論提出的觀點大體是這樣的:借助于“第三方”實現具有依賴關系的對象之間的解耦。如下圖:

 

IOC解耦過程

IOC解耦過程

 

大家看到了吧,由于引進了中間位置的“第三方”,也就是IOC容器,使得A、B、C、D這4個對象沒有了耦合關系,齒輪之間的傳動全部依靠“第三方”了,全部對象的控制權全部上繳給“第三方”IOC容器,所以,IOC容器成了整個系統的關鍵核心,它起到了一種類似“粘合劑”的作用,把系統中的所有對象粘合在一起發揮作用,如果沒有這個“粘合劑”,對象與對象之間會彼此失去聯系,這就是有人把IOC容器比喻成“粘合劑”的由來。

 

我們再來做個試驗:把上圖中間的IOC容器拿掉,然后再來看看這套系統:

 

拿掉IOC容器后的系統

拿掉IOC容器后的系統

 

我們現在看到的畫面,就是我們要實現整個系統所需要完成的全部內容。這時候,A、B、C、D這4個對象之間已經沒有了耦合關系,彼此毫無聯系,這樣的話,當你在實現A的時候,根本無須再去考慮B、C和D了,對象之間的依賴關系已經降低到了最低程度。所以,如果真能實現IOC容器,對于系統開發而言,這將是一件多么美好的事情,參與開發的每一成員只要實現自己的類就可以了,跟別人沒有任何關系!

 

我們再來看看,控制反轉(IOC)到底為什么要起這么個名字?我們來對比一下:

 

軟件系統在沒有引入IOC容器之前,如圖1所示,對象A依賴于對象B,那么對象A在初始化或者運行到某一點的時候,自己必須主動去創建對象B或者使用已經創建的對象B。無論是創建還是使用對象B,控制權都在自己手上。

 

軟件系統在引入IOC容器之后,這種情形就完全改變了,如圖3所示,由于IOC容器的加入,對象A與對象B之間失去了直接聯系,所以,當對象A運行到需要對象B的時候,IOC容器會主動創建一個對象B注入到對象A需要的地方。

 

通過前后的對比,我們不難看出來:對象A獲得依賴對象B的過程,由主動行為變為了被動行為,控制權顛倒過來了,這就是“控制反轉”這個名稱的由來。

 

93. spring 有哪些主要模塊?

 

Spring框架至今已集成了20多個模塊。這些模塊主要被分如下圖所示的核心容器、數據訪問/集成,、Web、AOP(面向切面編程)、工具、消息和測試模塊。

 

Spring框架主要模塊

 

94. spring 常用的注入方式有哪些?

 

Spring通過DI(依賴注入)實現IOC(控制反轉),常用的注入方式主要有三種:

 

 構造方法注入

 setter注入

 基于注解的注入

 

95. spring 中的 bean 是線程安全的嗎?

 

Spring容器中的Bean是否線程安全,容器本身并沒有提供Bean的線程安全策略,因此可以說spring容器中的Bean本身不具備線程安全的特性,但是具體還是要結合具體scope的Bean去研究。

 

96. spring 支持幾種 bean 的作用域?

 

當通過spring容器創建一個Bean實例時,不僅可以完成Bean實例的實例化,還可以為Bean指定特定的作用域。Spring支持如下5種作用域:

 

 singleton:單例模式,在整個Spring IoC容器中,使用singleton定義的Bean將只有一個實例

 

 prototype:原型模式,每次通過容器的getBean方法獲取prototype定義的Bean時,都將產生一個新的Bean實例

 

 equest:對于每次HTTP請求,使用request定義的Bean都將產生一個新實例,即每次HTTP請求將會產生不同的Bean實例。只有在Web應用中使用Spring時,該作用域才有效

 

 session:對于每次HTTP Session,使用session定義的Bean豆漿產生一個新實例。同樣只有在Web應用中使用Spring時,該作用域才有效

 

 globalsession:每個全局的HTTP Session,使用session定義的Bean都將產生一個新實例。典型情況下,僅在使用portlet context的時候有效。同樣只有在Web應用中使用Spring時,該作用域才有效

 

其中比較常用的是singleton和prototype兩種作用域。對于singleton作用域的Bean,每次請求該Bean都將獲得相同的實例。容器負責跟蹤Bean實例的狀態,負責維護Bean實例的生命周期行為;如果一個Bean被設置成prototype作用域,程序每次請求該id的Bean,Spring都會新建一個Bean實例,然后返回給程序。在這種情況下,Spring容器僅僅使用new 關鍵字創建Bean實例,一旦創建成功,容器不在跟蹤實例,也不會維護Bean實例的狀態。

 

如果不指定Bean的作用域,Spring默認使用singleton作用域。Java在創建Java實例時,需要進行內存申請;銷毀實例時,需要完成垃圾回收,這些工作都會導致系統開銷的增加。因此,prototype作用域Bean的創建、銷毀代價比較大。而singleton作用域的Bean實例一旦創建成功,可以重復使用。因此,除非必要,否則盡量避免將Bean被設置成prototype作用域。

 

97. spring 自動裝配 bean 有哪些方式?

 

Spring容器負責創建應用程序中的bean同時通過ID來協調這些對象之間的關系。作為開發人員,我們需要告訴Spring要創建哪些bean并且如何將其裝配到一起。

 

spring中bean裝配有兩種方式:

 

 隱式的bean發現機制和自動裝配

 在java代碼或者XML中進行顯示配置

 

當然這些方式也可以配合使用。

 

98. spring 事務實現方式有哪些?

 

 編程式事務管理對基于 POJO 的應用來說是唯一選擇。我們需要在代碼中調用beginTransaction()、commit()、rollback()等事務管理相關的方法,這就是編程式事務管理。

 

 基于 TransactionProxyFactoryBean 的聲明式事務管理

 

 基于 @Transactional 的聲明式事務管理

 

 基于 Aspectj AOP 配置事務

 

99. 說一下 spring 的事務隔離?

 

事務隔離級別指的是一個事務對數據的修改與另一個并行的事務的隔離程度,當多個事務同時訪問相同數據時,如果沒有采取必要的隔離機制,就可能發生以下問題:

 

 臟讀:一個事務讀到另一個事務未提交的更新數據。

 

 幻讀:例如第一個事務對一個表中的數據進行了修改,比如這種修改涉及到表中的“全部數據行”。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入“一行新數據”。那么,以后就會發生操作第一個事務的用戶發現表中還存在沒有修改的數據行,就好象發生了幻覺一樣。

 

 不可重復讀:比方說在同一個事務中先后執行兩條一模一樣的select語句,期間在此次事務中沒有執行過任何DDL語句,但先后得到的結果不一致,這就是不可重復讀。

 

100. 說一下 spring mvc 運行流程?

 

Spring MVC運行流程圖:

 

Spring MVC運行流程圖

 

Spring運行流程描述:

 

1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;

 

2. DispatcherServlet對請求URL進行解析,得到請求資源標識符(URI)。然后根據該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象(包括Handler對象以及Handler對象對應的攔截器),最后以HandlerExecutionChain對象的形式返回;

 

3. DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter;(附注:如果成功獲得HandlerAdapter后,此時將開始執行攔截器的preHandler(...)方法)

 

4.  提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程中,根據你的配置,Spring將幫你做一些額外的工作:

 

Java面試題-Spring

 

5.  Handler執行完成后,向DispatcherServlet 返回一個ModelAndView對象;

 

6.  根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經注冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;

 

7. ViewResolver 結合Model和View,來渲染視圖;

 

8. 將渲染結果返回給客戶端。

 

101. spring mvc 有哪些組件?

 

Spring MVC的核心組件:

 

 DispatcherServlet:中央控制器,把請求給轉發到具體的控制類

 

 Controller:具體處理請求的控制器

 

 HandlerMapping:映射處理器,負責映射中央處理器轉發給controller時的映射策略

 

 ModelAndView:服務層返回的數據和視圖層的封裝類

 

 ViewResolver:視圖解析器,解析具體的視圖

 

 Interceptors :攔截器,負責攔截我們定義的請求然后做處理工作

 

102. @RequestMapping 的作用是什么?

 

RequestMapping是一個用來處理請求地址映射的注解,可用于類或方法上。用于類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。

 

RequestMapping注解有六個屬性,下面我們把她分成三類進行說明。

 

value, method:

 

 value:指定請求的實際地址,指定的地址可以是URI Template 模式(后面將會說明);

 

 method:指定請求的method類型, GET、POST、PUT、DELETE等;

 

 consumes,produces

 consumes:指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;

 

 produces:指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回;

 

params,headers

 

 params: 指定request中必須包含某些參數值是,才讓該方法處理。

 

 headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。

 

103. @Autowired 的作用是什么?

 

@Autowired 是一個注釋,它可以對類成員變量、方法及構造函數進行標注,讓 spring 完成 bean 自動裝配的工作。

 

@Autowired 默認是按照類去匹配,配合 @Qualifier 指定按照名稱去裝配 bean。

 

常見用法

 

Java面試題-@Autowired 的常見用法

課程預約

极速1分彩_Welcome