關於Spring 和 Spring MVC的43面試題及答案
1.為什麼使用Spring ?
1). 方便解耦,簡化開發
通過Spring提供的IoC容器,可以將物件之間的依賴關係交由Spring進行控制,避免硬編碼所造成的過度程式耦合。
2). AOP程式設計的支援
通過Spring提供的AOP功能,方便進行面向切面的程式設計,如效能監測、事務管理、日誌記錄等。
3). 宣告式事務的支援
4). 方便整合各種優秀框架
5). 降低Java EE API的使用難度
如對JDBC,JavaMail,遠端呼叫等提供了簡便封裝。
2. 什麼是IoC,為什使用IoC ?
IoC全稱Iversion of Controller,控制反轉。
這概念是說你不用建立物件,而只需要描述它如何被建立。你不在程式碼裡直接組裝你的元件和服務,但是要在配置檔案裡描述哪些元件需要哪些服務,之後一個容器(IOC容器)負責把他們組裝起來。
它能指導我們如何設計出鬆耦合、更優良的程式。
3.什麼是AOP,為什麼使用AOP ?
AOP全稱:Aspect-Oriented Programming,面向切面程式設計。
AOP,面向切面程式設計,就是把可重用的功能提取出來,然後將這些通用功能在合適的時候織入到應用程式中,比如事務管理、許可權控制、日誌記錄、效能統計等。
AOP並沒有幫助我們解決任何新的問題,它只是提供了一種更好的辦法,能夠用更少的工作量來解決現有的一些問題,使得系統更加健壯,可維護性更好。
4.什麼是Spring的事務管理?
事務就是對一系列的資料庫操作(比如插入多條資料)進行統一的提交或回滾操作,如果插入成功,那麼一起成功,如果中間有一條出現異常,那麼回滾之前的所有操作。這樣可以防止出現髒資料,防止資料庫資料出現問題。
開發中為了避免這種情況一般都會進行事務管理。
Spring的宣告式事務通常是指在配置檔案中對事務進行配置宣告,其中包括了很多宣告屬性,它是通過Spring Proxy幫你做代理,自己不用額外的寫程式碼,只要在Spring配置檔案中宣告即可;通常用在資料庫的操作裡面;
程式設計式事務就是指通過硬編碼的方式做事務處理,這種處理方式需要寫程式碼,事務中的邏輯可以自己定製;可以是資料庫的東東,也可以是其他的操作。
Spring中也有自己的事務管理機制,一般是使用TransactionMananger進行管理,可以通過Spring的注入來完成此功能。
5.Spring框架支援以下五種bean的作用域?
singleton : 預設值,bean在每個Spring ioc 容器中只有一個例項。
prototype:一個bean的定義可以有多個例項。
request:每次http請求都會建立一個bean,該作用域僅在基於web的Spring ApplicationContext情形下有效。
session:在一個HTTP Session中,一個bean定義對應一個例項。該作用域僅在基於web的Spring ApplicationContext情形下有效。
global-session:在一個全域性的HTTP Session中,一個bean定義對應一個例項。該作用域僅在基於web的Spring ApplicationContext情形下有效。
6.什麼是Spring的MVC框架?
Spring 配備構建Web 應用的全功能MVC框架。Spring可以很便捷地和其他MVC框架整合,如Struts,Spring 的MVC框架用控制反轉把業務物件和控制邏輯清晰地隔離。它也允許以宣告的方式把請求引數和業務物件繫結。
spring mvc是一個基於mvc的web框架。spring mvc是spring框架的一個模組,springmvc和spring無需通過中間整合層進行整合。
7.如何啟用註解?
<context:annotation-config/>
如果使用<context:component-scan base-package="com.tgb.web.controller.annotation"> </context:component-scan> 則上面內容可以省略
8.Spring MVC的請求流程?
第一步:發起請求到前端控制器(DispatcherServlet)
第二步:前端控制器請求HandlerMapping查詢Handler可以根據xml配置、註解進行查詢
第三步:處理器對映器HandlerMapping向前端控制器返回Handler
第四步:前端控制器呼叫處理器介面卡去執行Handler
第五步:處理器介面卡去執行Handler
第六步:Handler執行完成給介面卡返回ModelAndView
第七步:處理器介面卡向前端控制器返回ModelAndView。ModelAndView是springmvc框架的一個底層物件,包括 Model和view
第八步:前端控制器請求檢視解析器去進行檢視解析,根據邏輯檢視名解析成真正的檢視(jsp)
第九步:檢視解析器向前端控制器返回View
第十步:前端控制器進行檢視渲染。檢視渲染將模型資料(在ModelAndView物件中)填充到request域
第十一步:前端控制器向用戶響應結果
9.web.xml的配置
10.註解的處理器對映器和介面卡?
spring3.1之後使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping註解對映器。
在spring3.1之後使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter註解介面卡。
使用 mvc:annotation-driven代替上邊註解對映器和註解介面卡配置
11.spring 與 mybatis整合過程?
第一步:整合dao層
mybatis和spring整合,通過spring管理mapper介面。
使用mapper的掃描器自動掃描mapper介面在spring中進行註冊。
第二步:整合service層
通過spring管理 service介面。
使用配置方式將service介面配置在spring配置檔案中。
實現事務控制。
第三步:整合springmvc
由於springmvc是spring的模組,不需要整合
主要配置有:
1). mybatis配置檔案sqlMapConfig.xml配置別名自動掃描(實體類)
2). mapper掃描器(介面,資料庫訪問介面)
3). 資料庫連線池配置
4). 宣告式事務配置
5). 啟用註解掃描:<context:component-scan base-package="cn.itcast.ssm.controller"></context:component-scan>
6). 配置註解對映器和介面卡: <mvc:annotation-driven></mvc:annotation-driven>
7). 檢視解析器:<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
8). 配置控制類: DispatcherServlet前端控制器
9). 配置spring配置檔案載入類:ClassLoadListener
12.檢視解析器配置字首和字尾?
13.sqlMapConfig.xml,mybatis自己的配置檔案?
14.配置資料來源?
15.事務控制(applicationContext-transaction.xml)?
在applicationContext-transaction.xml中使用spring宣告式事務控制方法。
16.載入spring配置?
17.靜態資源訪問不被攔截?
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/images/" />
<resources mapping="/js/**" location="/js/" />
1). url對映
2). 窄化請求對映
3). 限制http請求方法
19.controller方法的返回值?
1 返回ModelAndView
需要方法結束時,定義ModelAndView,將model和view分別進行設定。
2 返回string
如果controller方法返回string,
1). 表示返回邏輯檢視名。真正檢視(jsp路徑)=字首+邏輯檢視名+字尾
2). redirect重定向:返回字串格式為:"redirect:queryItem.action"
3). forward頁面轉發:返回字串格式為:“forward:queryItem.action”
3 返回void
在controller方法形參上可以定義request和response,使用request或 response指定響應結果:
1). 使用request轉向頁面,如下:request.getRequestDispatcher("頁面路徑").forward(request, response);
2). 也可以通過response頁面重定向:response.sendRedirect("url")
3). 也可以通過response指定響應結果,例如響應json資料如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
20.引數繫結
1 預設支援的型別
直接在controller方法形參上定義下邊型別的物件,就可以使用這些物件。在引數繫結過程中,如果遇到下邊型別直接進行繫結。
1). HttpServletRequest:通過request物件獲取請求資訊
2). HttpServletResponse:通過response處理響應資訊
3). HttpSession:通過session物件得到session中存放的物件
4). Model/ModelMap:model是一個介面,modelMap是一個介面實現 。作用:將model資料填充到request域。
2 簡單型別
通過@RequestParam對簡單型別的引數進行繫結。
如果不使用@RequestParam,要求request傳入引數名稱和controller方法的形參名稱一致,方可繫結成功。
如果使用@RequestParam,不用限制request傳入引數名稱和controller方法的形參名稱一致。
通過required屬性指定引數是否必須要傳入,如果設定為true,沒有傳入引數,會報錯。
3 pojo繫結
頁面中input的name和controller的pojo形參中的屬性名稱一致,將頁面中資料繫結到pojo。(usename,age;不需要user.username,user.age)
4 自定義引數繫結實現日期型別繫結
對於controller形參中pojo物件,如果屬性中有日期型別,需要自定義引數繫結。將請求日期資料串轉成 日期型別,要轉換的日期型別和pojo中日期屬性的型別保持一致。
21.Spring MVC 和 Struts2 對比?
1). Struts2是類級別的攔截, 一個類對應一個request上下文,SpringMVC是方法級別的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上SpringMVC 就容易實現restful url
2). 由上邊原因,SpringMVC的方法之間基本上獨立的,獨享request response資料,請求資料通過引數獲取,處理結果通過ModelMap交回給框架,方法之間不共享變數,而Struts2搞的就比較亂,雖然方法之間也是獨立的,但其所有Action變數是共享的,這不會影響程式執行,卻給我們編碼 讀程式時帶來麻煩,每次來了請求就建立一個Action,一個Action物件對應一個request上下文。
3). 由於Struts2需要針對每個request進行封裝,把request,session等servlet生命週期的變數封裝成一個一個Map,供給每個Action使用,並保證執行緒安全,所以在原則上,是比較耗費記憶體的。
4). SpringMVC集成了Ajax,使用非常方便,只需一個註解@ResponseBody就可以實現,然後直接返回響應文字即可,而Struts2攔截器集成了Ajax,在Action中處理時一般必須安裝外掛或者自己寫程式碼整合進去,使用起來也相對不方便。
5). springmvc面向方法開發的(更接近service介面的開發方式),struts2面向類開發。
6). springmvc可以單例開發,struts2只能是多例開發。
22. 亂碼處理?
1). post亂碼
在web.xml新增post亂碼filter:CharacterEncodingFilter
2). 對於get請求中文引數出現亂碼解決方法有兩個:
a. 修改tomcat配置檔案新增編碼與工程編碼一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
b. 對引數進行重新編碼:
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat預設編碼,需要將tomcat編碼後的內容按utf-8編碼
23. 集合型別繫結
1). 陣列繫結:
controller方法引數使用:(Integer[] itemId)
頁面統一使用:itemId 作為name
2). list繫結:
pojo屬性名為:itemsList
頁面:itemsList[index].屬性名
3). map 繫結:
pojo屬性名為:Map<String, Object> itemInfo = new HashMap<String, Object>();
頁面: <td>姓名:<inputtype="text"name="itemInfo['name']"/>
24.spring 校驗 ?
1). 專案中,通常使用較多是前端的校驗,比如頁面中js校驗。對於安全要求較高點建議在服務端進行校驗。
2). springmvc使用hibernate的校驗框架validation(和hibernate沒有任何關係)。
校驗思路:頁面提交請求的引數,請求到controller方法中,使用validation進行校驗。如果校驗出錯,將錯誤資訊展示到頁面。
25.資料回顯?
1). @ModelAttribute還可以將方法的返回值傳到頁面:在方法上加註解@ModelAttribute
2). 使用最簡單方法使用model,可以不用@ModelAttribute:model.addAttribute("id", id);
3). springmvc預設對pojo資料進行回顯。pojo資料傳入controller方法後,springmvc自動將pojo資料放到request域,key等於pojo型別(首字母小寫)
4). public String testParam(PrintWriter out, @RequestParam("username") String username) { //out直接輸出
26.異常處理?
springmvc提供全域性異常處理器(一個系統只有一個異常處理器)進行統一異常處理。
系統遇到異常,在程式中手動丟擲,dao拋給service、service給controller、controller拋給前端控制器,前端控制器呼叫全域性異常處理器。
27.上傳圖片?
1). 在頁面form中提交enctype="multipart/form-data"的資料時,需要springmvc對multipart型別的資料進行解析。
2). 在springmvc.xml中配置multipart型別解析器。
3). 方法中使用:MultipartFile attach (單個檔案上傳) 或者 MultipartFile[] attachs (多個檔案上傳)
28.Json處理
1). 載入json轉換的jar包:springmvc中使用jackson的包進行json轉換(@requestBody和@responseBody使用下邊的包進行json轉)
2). 配置json轉換器。在註解介面卡RequestMappingHandlerAdapter中加入messageConverters。如果使用<mvc:annotation-driven /> 則會自動加入。
3). ajax
4). Controller (ResponseBody、RequestBody)
5). 注意ajax中contentType如果不設定為json型別,則傳的引數為key/value型別。上面設定後,傳的是json型別。
29.攔截器?
1). 定義攔截器,實現HandlerInterceptor介面。介面中提供三個方法。
a. preHandle :進入 Handler方法之前執行,用於身份認證、身份授權,比如身份認證,如果認證通過表示當前使用者沒有登陸,需要此方法攔截不再向下執行
b. postHandle:進入Handler方法之後,返回modelAndView之前執行,應用場景從modelAndView出發:將公用的模型資料(比如選單導航)在這裡傳到檢視,也可以在這裡統一指定檢視
c. afterCompletion:執行Handler完成執行此方法,應用場景:統一異常處理,統一日誌處理
2). 攔截器配置:
a. 針對HandlerMapping配置(不推薦):springmvc攔截器針對HandlerMapping進行攔截設定,如果在某個HandlerMapping中配置攔截,經過該 HandlerMapping對映成功的handler最終使用該 攔截器。 (一般不推薦使用)
b. 類似全域性的攔截器:springmvc配置類似全域性的攔截器,springmvc框架將配置的類似全域性的攔截器注入到每個HandlerMapping中
30.spring中自動裝配的方式有哪些?
1、No:即不啟用自動裝配。
2、byName:通過屬性的名字的方式查詢JavaBean依賴的物件併為其注入。比如說類Computer有個屬性printer,指定其autowire屬性為byName後,Spring IoC容器會在配置檔案中查詢id/name屬性為printer的bean,然後使用Seter方法為其注入。
3、byType:通過屬性的型別查詢JavaBean依賴的物件併為其注入。比如類Computer有個屬性printer,型別為Printer,那麼,指定其autowire屬性為byType後,Spring IoC容器會查詢Class屬性為Printer的bean,使用Seter方法為其注入。
4、constructor:通byType一樣,也是通過型別查詢依賴物件。與byType的區別在於它不是使用Seter方法注入,而是使用構造子注入。
5、autodetect:在byType和constructor之間自動的選擇注入方式。
6、default:由上級標籤<beans>的default-autowire屬性確定。
31.Spring中AOP的應用場景、Aop原理、好處?
AOP--Aspect Oriented Programming面向切面程式設計;用來封裝橫切關注點,具體可以在下面的場景中使用:
Authentication 許可權、Caching 快取、Context passing 內容傳遞、Error handling 錯誤處理Lazy loading懶載入、Debugging除錯、logging, tracing, profiling and monitoring 記錄跟蹤優化 校準、Performance optimization 效能優化、Persistence 持久化、Resource pooling 資源池、Synchronization 同步、Transactions 事務。
原理:AOP是面向切面程式設計,是通過動態代理的方式為程式新增統一功能,集中解決一些公共問題。
優點:1.各個步驟之間的良好隔離性耦合性大大降低 2.原始碼無關性,再擴充套件功能的同時不對原始碼進行修改操作
32.Spring中IOC的作用與原理?物件建立的過程?
IOC--Inversion of Control控制反轉。當某個角色需要另外一個角色協助的時候,在傳統的程式設計過程中,通常由呼叫者來建立被呼叫者的例項物件。但在spring中建立被呼叫者的工作不再由呼叫者來完成,因此稱為控制反轉。建立被呼叫者的工作由spring來完成,然後注入呼叫者 直接使用。
33.Spring常見建立物件的註解?
@[email protected]@ [email protected] Repository
34.Spring中用到的設計模式?
簡單工廠、工廠方法、單例模式、介面卡、包裝器、代理、觀察者、策略、模板方法
35.Spring的優點?
1.降低了元件之間的耦合性 ,實現了軟體各層之間的解耦 2.可以使用容易提供的眾多服務,如事務管理,訊息服務等 3.容器提供單例模式支援 4.容器提供了AOP技術,利用它很容易實現如許可權攔截,執行期監控等功能 5.容器提供了眾多的輔助類,能加快應用的開發 6.spring對於主流的應用框架提供了整合支援,如hibernate,JPA,Struts等 7.spring屬於低侵入式設計,程式碼的汙染極低 8.獨立於各種應用伺服器 9.spring的DI機制降低了業務物件替換的複雜性 10.Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可以自由選擇spring的部分或全部
36.Spring Bean的作用域之間有什麼區別?
Spring容器中的bean可以分為5個範圍。所有範圍的名稱都是自說明的,但是為了避免混淆,還是讓我們來解釋一下:
singleton:這種bean範圍是預設的,這種範圍確保不管接受到多少個請求,每個容器中只有一個bean的例項,單例的模式由bean factory自身來維護。
prototype:原形範圍與單例範圍相反,為每一個bean請求提供一個例項。
request:在請求bean範圍內會每一個來自客戶端的網路請求建立一個例項,在請求完成以後,bean會失效並被垃圾回收器回收。
Session:與請求範圍類似,確保每個session中有一個bean的例項,在session過期後,bean會隨之失效。
global-session:global-session和Portlet應用相關。當你的應用部署在Portlet容器中工作時,它包含很多portlet。如果你想要宣告讓所有的portlet共用全域性的儲存變數的話,那麼這全域性變數需要儲存在global-session中。
全域性作用域與Servlet中的session作用域效果相同。
37.Spring管理事務有幾種方式?
有兩種方式:
1、程式設計式事務,在程式碼中硬編碼。(不推薦使用)
2、宣告式事務,在配置檔案中配置(推薦使用)
宣告式事務又分為兩種:
a、基於XML的宣告式事務
b、基於註解的宣告式事務
38.spring中的核心類有那些,各有什麼作用?
BeanFactory:產生一個新的例項,可以實現單例模式
BeanWrapper:提供統一的get及set方法
ApplicationContext:提供框架的實現,包括BeanFactory的所有功能
39.Bean的呼叫方式有哪些?
有三種方式可以得到Bean並進行呼叫: 1、使用BeanWrapper HelloWorld hw=new HelloWorld(); BeanWrapper bw=new BeanWrapperImpl(hw); bw.setPropertyvalue(”msg”,”HelloWorld”); system.out.println(bw.getPropertyCalue(”msg”));
2、使用BeanFactory InputStream is=new FileInputStream(”config.xml”); XmlBeanFactory factory=new XmlBeanFactory(is); HelloWorld hw=(HelloWorld) factory.getBean(”HelloWorld”); system.out.println(hw.getMsg());
3、使用ApplicationConttext ApplicationContext actx=new FleSystemXmlApplicationContext(”config.xml”); HelloWorld hw=(HelloWorld) actx.getBean(”HelloWorld”); System.out.println(hw.getMsg());
40.什麼是IOC,什麼又是DI,他們有什麼區別?
依賴注入DI是一個程式設計模式和架構模型, 一些時候也稱作控制反轉,儘管在技術上來講,依賴注入是一個IOC的特殊實現,依賴注入是指一個物件應用另外一個物件來提供一個特殊的能力,例如:把一個 資料庫連線已引數的形式傳到一個物件的結構方法裡面而不是在那個物件內部自行建立一個連線。控制反轉和依賴注入的基本思想就是把類的依賴從類內部轉化到外 部以減少依賴
應用控制反轉,物件在被建立的時候,由一個調控系統內所有物件的外界實體,將其所依賴的物件的引用,傳遞給它。也可以說,依賴被注入到物件中。所以,控制反轉是,關於一個物件如何獲取他所依賴的物件的引用,這個責任的反轉。
41.spring有兩種代理方式?
若目標物件實現了若干介面,spring使用JDK的java.lang.reflect.Proxy類代理。
優點:因為有介面,所以使系統更加鬆耦合
缺點:為每一個目標類建立介面
若目標物件沒有實現任何介面,spring使用CGLIB庫生成目標物件的子類。
優點:因為代理類與目標類是繼承關係,所以不需要有介面的存在。
缺點:因為沒有使用介面,所以系統的耦合性沒有使用JDK的動態代理好。
42.springMVC的流程?
1.使用者傳送請求至前端控制器DispatcherServlet
2.DispatcherServlet收到請求呼叫HandlerMapping處理器對映器。
3.處理器對映器根據請求url找到具體的處理器,生成處理器物件及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
4.DispatcherServlet通過HandlerAdapter處理器介面卡呼叫處理器
5.執行處理器(Controller,也叫後端控制器)。
6.Controller執行完成返回ModelAndView
7.HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
8.DispatcherServlet將ModelAndView傳給ViewReslover檢視解析器
9.ViewReslover解析後返回具體View
10.DispatcherServlet對View進行渲染檢視(即將模型資料填充至檢視中)。
11.DispatcherServlet響應使用者
43.Springmvc的優點?
1.它是基於元件技術的.全部的應用物件,無論控制器和檢視,還是業務物件之類的都是 java元件.並且和Spring提供的其他基礎結構緊密整合.
2.不依賴於Servlet API(目標雖是如此,但是在實現的時候確實是依賴於Servlet的)
3. 可以任意使用各種檢視技術,而不僅僅侷限於JSP
4 . 支援各種請求資源的對映策略
5 .它應是易於擴充套件的