myBatis+Spring+SpringMVC框架面試題整理(一)
目錄
■ 如何解決 get 和 post 亂碼問題?
■ 簡單介紹一下 Spring bean 的生命周期(11步)
■ 如何構建一個線程安全的SqlSession
■ SpringMVC 的工作原理
首先:讀取配置文件
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將幫你做一些額外的工作:
HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息
數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
數據格式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
5. Handler執行完成后,向DispatcherServlet 返回一個ModelAndView對象;
6. 根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經注冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;
7. ViewResolver 結合Model和View,來渲染視圖
8. 將渲染結果返回給客戶端。
■ 談談你對SpringMVC的理解
1. 是一個基於MVC的web框架
2. SpringMVC是Spring的一個模塊,是Spring的子容器,子容器可以拿父容器的東西,但是父容器不能拿子容器的東西
3. SpringMVC的前端控制器DispatcherServlet,用於分發請求,使開發變得簡單
4. SpringMVC流程(重點)
5. SpringMVC三大組件
1)HandlerMapping:處理器映射器
用戶請求路徑到Controller方法的映射
2)HandlerAdapter:處理器適配器
根據handler(controlelr類)的開發方式(注解開發/其他開發) 方式的不同去尋找不同的處理器適配器
3)ViewResolver:視圖解析器
可以解析JSP/freemarkerr/pdf等
■ SpringMVC 常用注解都有哪些?
1. @Controller,使用它標記的類就是一個SpringMVC Controller 對象
2. @RequestMapping,處理請求映射地址
3. @PathVariable,用於對應restful風格url中的參數
@RequestMapping(value="/happy/{dayid}")
findPet(@PathVariable String dayid)
4. @RequestParam,將請求的參數綁定到方法中的參數上
@RequestParam(value = "name", required = false) String name
5. @ResponseBody,將返回類型直接輸入到http response body中
6. @RequestBody,方法參數直接被綁定到http request body中
7. @ModelAttribute和@SessionAttributes,用來傳遞和保存數據,有很多的坑,不建議使用
■ Spring 的常用注解
1. 控制反轉
@Component,標注為一個普通的bean
@Service,@Repository
2. 依賴注入
@Autowired
@Qulifier
@Resource
@Value
3. 全局
@Configuration,代替配置文件,相當於beans
@ComponentScan,配置掃描包
@Scope,配置bean的生命周期
■ 如何開啟注解處理器和適配器?
<mvc:annontation-driven/>
■ 如何解決 get 和 post 亂碼問題?
1. get亂碼,手動轉換
首先:
String name = new String(xx.getBytes(“iso-8859-1”),”utf-8”);
不行的化,再:
在server.xml中,修改編碼和工程編碼一致
2. post亂碼,在web.xml中配置字符過濾的filter,采用的類是Spring的CharacterEncodingFilter
-
<filter>
-
-
<filter-name>CharacterEncodingFilter</filter-name>
-
-
<filter-class>
-
-
org.springframework.web.filter.CharacterEncodingFilter
-
-
</filter-class>
-
-
<init-param>
-
-
<param-name>encoding</param-name>
-
-
<param-value>utf-8</param-value>
-
-
</init-param>
-
-
</filter>
-
-
<filter-mapping>
-
-
<filter-name>CharacterEncodingFilter</filter-name>
-
-
<url-pattern>/*</url-pattern>
-
-
</filter-mapping>
原因:
使用注解@RequestBody和@ResponseBody時,request.setCharactorEncoding(“utf-8”),不起作用。
■ 談談你對 Spring 的理解
1. 是一個容器框架
2. 非侵入式框架,框架不會影響或者改變我們原有的編碼過程
3. 是一個輕量級框架,可以自由選擇Spring框架的全部或一部分
4. 是一個一站式框架,提供了各種各樣的模塊,支持開發
5. 提供了對於持久層的支持
6. 提供了Web MVC框架
7. IOC/DI,控制反轉/依賴注入(解釋一下)
控制反轉
不是一種技術,而是一個面向對象編程的法則,“好萊塢法則”,即“don’t call us,we’ll call you”,“別找我,我回來找你”。
控制反轉是從容器的角度來說的,以前對象都是應用程序new出來的,對象之間的依賴也是應用程序自己創建的,從而導致類與類之間高耦合,難於測試。現在,由Spring管理bean的生命周期以及bean之間的關系,降低了業務對象替換的復雜性,提高了組件之間的解耦。
對資源進行集中管理,實現了資源的可配置和易管理;
隱藏細節,不用自己組裝,我們只負責調用。
依賴注入
是從應用程序的角度來說的,即,應用程序依賴Spring管理的bean以及bean之間的關系。Spring容器中有很多bean的實例,它會將符合依賴關系的對象通過注入的方式進行關聯,建立bean與bean之間的聯系。
常見注入方式有:屬性注入,構造器注入,數組注入,集合注入。
8. AOP,面向切面編程(解釋一下)
利用一種稱為“橫切”的技術,支持將公共業務提取出來(例如:安全/事務/日志)進行集中管理,面向核心業務編程,只需要關注業務本身,而不用去關注公共業務。使用AOP可以將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重復代碼,降低模塊間的耦合度,並有利於未來的可操作性和可維護性。
Spring中實現AOP的方式有三種,分別為,基於AspectJ注解方式實現、基於Schema的xml配置、基於ProxyFactoryBean代理實現,但是底層都是基於動態代理實現的,動態代理有JDK動態代理和CGLIB動態代理,AOP默認使用的是JDK動態代理,當目標類沒有接口時,使用CGLIB動態代理,也可以在配置文件中配置proxy-target-class=true,只使用CGLIB動態代理。
■ Spring 中的設計模式(解釋)
Spring中共用到9種設計模式:
工廠模式,單例模式,代理模式,包裝器模式,適配器模式,簡單工廠模式,觀察者模式,策略模式,模板方法模式
1. 工廠模式
定義一個用於創建對象的接口,讓子類決定實例化哪一個類。
Spring中FactoryBean就是典型的工廠方法模式
2. 單例模式
保證一個類只有一個實例,並提供一個訪問它的全局訪問點。
Spring的單例模式完成了后半句化,即提供了全局的訪問點BeanFactory
3. 包裝器模式
動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式相比生成子類更為靈活。
Spring中用到的包裝器模式在類名上有兩種表現:一種是類名中含有Wrapper,另一種是類名中含有Decorator。基本上都是動態地給一個對象添加一些額外的職責。
4. 代理模式
為其他對象提供一種代理以控制對這個對象的訪問。
Spring的Proxy模式在aop中有體現,比如JdkDynamicAopProxy和Cglib2AopProxy。
5. 適配器模式,HandlerAdapter
將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。
Spring中在對於AOP的處理中有Adapter模式的例子,見如下圖:
由於Advisor鏈需要的是MethodInterceptor(攔截器)對象,所以每一個Advisor中的Advice都要適配成對應的MethodInterceptor對象。
6. 簡單工廠模式
簡單工廠模式的實質是由一個工廠類根據傳入的參數,動態決定應該創建哪一個產品類。
BeanFactory,根據傳入一個唯一的標識來獲得bean對象,但不屬於23種GOF設計模式之一。
■ 簡單介紹一下 Spring bean 的生命周期(11步)
前提是實體類實現了相應的接口
spring上下文中的bean的生命周期:
1.實例化bean對象
2.注入bean的所有屬性
3.設置bean的id
調用BeanNameAware接口的setBeanName(String)方法
4.設置bean工廠
調用BeanFactoryAware接口的setBeanFactory()方法
5.設置實例所在的上下文空間
調用ApplicationContextAware接口的setApplicationContext()方法,傳入Spring上下文
6.調用后置處理器的預初始化方法
調用BeanPostProcessor接口的postProcessorBeforeInitialization()方法
7.執行InitializingBean的afterPropertiesSet()
8.調用使用init-method配置的自定義初始化方法
9.調用后置處理器的后初始化方法
調用BeanPostProcessor接口的postProcessorAfterInitialization()方法
10.調用DisPosableBean接口的destory()方法
11.調用使用destroy-method配置的自定義銷毀由方法
由BeanFactroy創建的bean
沒有第五步
■ 如何構建一個線程安全的SqlSession
請參看我的另外一篇博客:https://blog.csdn.net/qq_41541619/article/details/82528871
myBatis+Spring+SpringMVC框架面試題整理(二)
目錄
■ 什么是 Spring IOC 容器,IOC 的優點是什么?
■ Spring 支持的幾種 bean 的作用域
■ 使用 MyBatis 的 mapper 接口調用時有哪些要求
■ mybatis的緩存機制,一級,二級介紹一下
■ Spring 能幫我們做什么
1. 實例化bean,並且管理bean與bean之間的依賴關系
2. Spring面向切面編程能幫助我們無耦合實現日志記錄,性能統計,安全控制等功能
3. Spring能非常簡單的幫我們管理數據庫事務
4. Spring提供了與第三方框架無縫集成,如:
第三方數據訪問框架(mybatis,hibernate,jpa),自身提供了JDBC訪問;
第三方web框架(struts,jsf),自己提供了spring mvc進行web創建;
其他第三方框架(如:java mail,任務調度,緩存框架等)
■ 描述一下 Spring 的事務
1. 事務的特性ACID
原子性、一致性、隔離性、持久性
2. 事務是一系列操作的最小單元,在Spring中,一個session對應一個事務,要么全部成功要么全部失敗,如果中間有一條出現異常,那么回滾之前的所有操作
3. Spring中有自己的事務管理機制,實現方式共有兩種:編程式和聲明式。
編程式事務:使用TransactionTemplate,重寫execute方法實現事務管理
聲明式事務:使用AOP面向切面編程實現,本質就是在目標方法執行前后進行攔截。在目標方法執行前加入或創建一個事務,在執行方法執行后,根據實際情況選擇提交或是回滾事務。
實現聲明式事務管理又有兩種方式:
基於XML配置文件;
基於注解,使用@Transactional注解,將事務規則應用到業務邏輯中
4. 事務最重要的兩個特性是事務的傳播級別(7種)和數據隔離級別(4種)
傳播級別定義的是事務的控制范圍。
我使用過的是REQUIRED和SUPPORTS
REQUIRED(增刪改):在事務中執行,如果沒有事務存在,則會重新創建一個。
SUPPORTS(查):使用當前的環境執行,如果當前存在事務,則使用這個事務;如果當前沒有事務,則不使用事務
事務隔離級別定義的是事務在數據庫讀寫方面的控制范圍。
未授權讀取,授權讀取,可重復讀取,序列化(隔離級別最高)
事務隔離的實現是基於悲觀鎖和樂觀鎖
Mysql默認的隔離級別是可重復讀
■ 什么是 Spring IOC 容器,IOC 的優點是什么?
1. IOC容器可以理解為一個創建和管理bean的容器,用於創建bean的實例並且管理bean和bean之間的關系
2. 優點(3點)
1) 以前對象都是應用程序new出來的,對象之間的依賴也是應用程序自己創建的,從而導致類與類之間高耦合,難於測試。現在,由Spring管理bean的生命周期以及bean之間的關系,降低了業務對象替換的復雜性,提高了組件之間的解耦;
2) 對資源進行集中管理,實現了資源的可配置和易管理;
3)隱藏細節,不用自己組裝,我們只負責調用。
■ 什么是 Spring 的依賴注入 ,注入方式有哪些?
1. 依賴注入,是IOC的一方面,是一個通常的概念,它有多種解釋。這個概念是說我們不用創建對象,而只需要描述它是如何被創建。我們不用在代碼里直接組裝組件和服務,但是要在配置文件里描述哪些組件需要哪些服務,之后由IOC容器負責把他們組裝起來。
2. 注入方式,實現方式分為兩類,基於配置文件和基於注解
屬性注入
構造器注入
數組注入
集合注入
List注入
Map注入
■ Spring 支持的幾種 bean 的作用域
1. Singleton,單例,每個bean在Spring IOC容器中只有一個實例,缺省作用域
2. Prototype,原型,每次使用的使用,都會創建一個新的實例
3. Session,在一個HttpSession中,一個bean定義對應一個實例
4. Request,每次http請求都會創建一個bean
5. GlobalSession,在一個全局的HttpSession中,一個bean定義對應一個實例
6. Application
7. Socket
■ 簡單解釋一下 spring 的 AOP
利用一種稱為“橫切”的技術,支持將公共業務提取出來(例如:安全/事務/日志)進行集中管理,面向核心業務編程,只需要關注業務本身,而不用去關注公共業務。使用AOP可以將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重復代碼,降低模塊間的耦合度,並有利於未來的可操作性和可維護性。
Spring中實現AOP的方式有三種,分別為,基於AspectJ注解方式實現、基於Schema的xml配置、基於ProxyFactoryBean代理實現,但是底層都是基於動態代理實現的,動態代理有JDK動態代理和CGLIB動態代理,AOP默認使用的是JDK動態代理,當目標類沒有接口時,使用CGLIB動態代理,也可以在配置文件中配置proxy-target-class=true,只使用CGLIB動態代理。
Spring切面可以應用五種類型的通知
1. 前置通知
2. 后置通知
3. 環繞通知
4. 返回后通知
5. 異常通知
AOP術語
1. 切面(Aspect):公共功能、交叉功能的描述
2. 通知(Advice):實現切面功能的類,真正做事情的地方
3. 連接點(Joinpoint):靜態概念,通知執行的地方
4. 切入點(PointCut):動態概念,運行時執行通知的地方,實現切面功能時,連接點變為切入點
5. 目標對象(Target):被通知的對象,核心關注點對象
6. 代理對象(Proxy):代理的是目標對象,通過代理目標對象就增加了切面功能
7. 引入(Introductions):靜態概念,將切面與目標對象關聯起來
8. 織入(Weaving):將切面應用到代理對象,是一個過程
■ Mybatis 中#和$的區別?
1. #{}是預編譯處理,${}是字符串替換。
2. Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值;
3. Mybatis在處理${}時,就是把${}替換成變量的值,相當於字符串拼接
4. 使用#{}可以有效的防止SQL注入,提高系統安全性。
■ Mybatis 的使用步驟是什么樣的?
1. 讀取配置文件
2. 創建SqlSessionFactoty
3. 創建SqlSession
4. 操作數據庫
5. 提交事務(增刪改)
6. 關閉session
■ 使用 MyBatis 的 mapper 接口調用時有哪些要求
1. namespace命名空間指向一個特定的dao接口(全路徑)
2. 每一個sql中的id,唯一標識接口中的一個方法
3. parameterType對應接口方法中的輸入參數類型
4. resultType對應接口方法的返回類型
5. 參數多個怎么做
map,索引,注解@Param
■ mybatis的緩存機制,一級,二級介紹一下
1. 一級緩存
默認開啟
SqlSession級別的緩存,實現在同一個會話中數據的共享
一級緩存的生命周期和SqlSession一致
當有多個SqlSession或者分布式環境下,數據庫寫操作會引起臟數據。
2. 二級緩存
默認不開啟,需手動開啟
SqlSessionFactory級別的緩存,實現不同會話中數據的共享,是一個全局變量
可自定義存儲源,如Ehcache
當開啟緩存后,數據查詢的執行的流程是:二級緩存>一級緩存>數據庫
不同於一級緩存,二級緩存可設置是否允許刷新和刷新頻率
實現
實體類實現序列化
在mapper文件中開啟<cache>
在配置文件中設置cacheEnabled為true
■ 視圖解析器本質是什么
轉發,隱藏細節
■ 統一解決get亂碼
傳參之前,將數據序列化