面試必會 --> SSM篇
01-什么是Spring IOC 和DI ?
IOC : 控制翻轉(zhuǎn) , 它把傳統(tǒng)上由程序代碼直接操控的對象的調(diào)用權(quán)交給容 器,通過容器來實現(xiàn)對
象組件的裝配和管理。所謂的“控制反轉(zhuǎn)”概念就是對組件對象控制權(quán)的轉(zhuǎn) 移,從程序代碼本身
轉(zhuǎn)移到了外部容器。
DI : 依賴注入,在我們創(chuàng)建對象的過程中,把對象依賴的屬性注入到我們的類中。
02-有哪些不同類型的依賴注入實現(xiàn)方式?
依賴注入分為接口注入,Setter方 法注入和構(gòu)造器注入以及注解注入
-
構(gòu)造器注入 : 顧名思義, 就是在類中提供有參構(gòu)造方法, 創(chuàng)建Bean的時候會自動執(zhí)行構(gòu)造方
法將依賴數(shù)據(jù)注入進去
-
Setter方法注入 : 顧名思義, 就是提供屬性對應(yīng)的setter方法 , 創(chuàng)建Bean的時候會自動執(zhí)行
Setter方法將依賴數(shù)據(jù)注入進去
-
注解注入 : 就是在屬性上使用一些注入注入數(shù)據(jù), 經(jīng)常用的有 @Autowired , @Resource
,@Qualifier 注解
@Autowired : 默認(rèn)根據(jù)類型注入 , 按照類型匹配多個Bean,再按照屬性名稱注入
@Resource : 默認(rèn)按照名稱注入 , 如果找不到對應(yīng)的Bean,按照類型注入 , 也可以指定
按照名稱注入(name)或者按照類型注入(type)
@Qualifier : 結(jié)合@Autowired注解一起使用, 如果按照類型匹配多個Bean , 通過
@Qualifier注解指定按照名稱注入的屬性名稱
03- Spring支持的幾種bean的作用域 Scope
Spring框架支持以下五種bean的作用域:
-
singleton : bean在每個Spring ioc 容器中只有一個實例。
-
prototype:一個bean的定義可以有多個實例。
-
request:每次http請求都會創(chuàng)建一個bean,該作用域僅在基于web的Spring
ApplicationContext情形下有效。
-
session:在一個HTTP Session中,一個bean定義對應(yīng)一個實例。該作用域僅在基于web
的 Spring ApplicationContext情形下有效。
-
global-session:在一個全局的HTTP Session中,一個bean定義對應(yīng)一個實例。該作用域
僅在基 于web的Spring ApplicationContext情形下有效。
04- Spring框架中的單例bean是線程安全的嗎?
不是,Spring框架中的單例bean不是線程安全的 , spring 中的 bean 默認(rèn)是單例模式,spring 框架并沒有對單例 bean 進行多線程的封裝處理。
但是我們一般在使用單例Bean的時候, 不會設(shè)置共享數(shù)據(jù), 所以也就不會存在線程安全問題 ! 從這個角度講單例bean也是線程安全的
05- spring 自動裝配 bean 有哪些方式?
在Spring框架xml配置中共有5種自動裝配:
-
byName:通過bean的名稱進行自動裝配,如果一個bean的 property 與另一bean 的
name 相 同,就進行自動裝配。
-
byType:通過參數(shù)的數(shù)據(jù)類型進行自動裝配。
-
constructor:利用構(gòu)造函數(shù)進行裝配,并且構(gòu)造函數(shù)的參數(shù)通過byType進行裝配。
-
setter方法 : 根據(jù)屬性的setter方法注入
-
注解注入
09- JDK動態(tài)代理和CGLIB動態(tài)代理的區(qū)別
Spring AOP中的動態(tài)代理主要有兩種方式,JDK動態(tài)代理和CGLIB動態(tài)代理:
-
JDK動態(tài)代理只提供接口的代理,不支持類的代理
Proxy.newProxyInstance(類加載器, 代理對象實現(xiàn)的所有接口, 代理執(zhí)行器) -
CGLIB是通過繼承的方式做的動態(tài)代理 , 如果某個類被標(biāo)記為final,那么它是無法使用 CGLIB做動態(tài)代理的。
Enhancer.create(父類的字節(jié)碼對象, 代理執(zhí)行器)
10- 什么是AOP , 你們項目中有沒有使用到AOP
AOP一般稱為面向切面編程,作為面向?qū)ο蟮囊环N補充,用于 將那些與業(yè)務(wù)無關(guān),但卻對多個
對象產(chǎn)生影響的公共行為和邏輯,抽取并封裝為一個可重用的模 塊,這個模塊被命名為“切面”
(Aspect),減少系統(tǒng)中的重復(fù)代碼,降低了模塊間的耦合度,同時 提高了系統(tǒng)的可維護性。
在我們的項目中我們自己寫AOP的場景其實很少 , 但是我們使用的很多框架的功能底層都是AOP
, 例如 : 權(quán)限認(rèn)證、日志、事務(wù)處理等
11- SpringMVC的執(zhí)行流程知道嘛

-
用戶發(fā)送請求至前端控制器DispatcherServlet;
-
DispatcherServlet收到請求后,調(diào)用HandlerMapping處理器映射器,請求獲取Handle;
-
處理器映射器根據(jù)請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生
成)一并返回給DispatcherServlet;
-
DispatcherServlet 調(diào)用 HandlerAdapter處理器適配器;
-
HandlerAdapter 經(jīng)過適配調(diào)用具體處理器(Handler,也叫后端控制器);
-
Handler執(zhí)行完成返回ModelAndView;
-
HandlerAdapter將Handler執(zhí)行結(jié)果ModelAndView返回給DispatcherServlet;
-
DispatcherServlet將ModelAndView傳給ViewResolver視圖解析器進行解析;
-
ViewResolver解析后返回具體View;
-
DispatcherServlet對View進行渲染視圖(即將模型數(shù)據(jù)填充至視圖中)
-
DispatcherServlet響應(yīng)用戶
12- Spring MVC常用的注解有哪些?
@RequestMapping:用于處理請求 url 映射的注解,可用于類或方法上。用于類上,則表示類中 的所有響應(yīng)請求的
方法都是以該地址作為父路徑。
@RequestBody:注解實現(xiàn)接收http請求的json數(shù)據(jù),將json轉(zhuǎn)換為java對象。
@ResponseBody:注解實現(xiàn)將conreoller方法返回對象轉(zhuǎn)化為json對象響應(yīng)給客戶。
@Controller:控制器的注解,表示是表現(xiàn)層,不能用用別的注解代替
@RestController : 組合注解 @Conntroller + @ResponseBody
@GetMapping , @PostMapping , @PutMapping , @DeleteMapping ...
@PathVariable : 接收請求路徑中的變量
@RequestParam : 接收請求參數(shù)
13- Mybatis #{}和${}的區(qū)別
#{}是占位符,預(yù)編譯處理;${}是拼接符,字符串替換,沒有預(yù)編譯處理。
Mybatis在處理#{}時,#{}傳入?yún)?shù)是以字符串傳入,會將SQL中的#{}替換為?號,調(diào)用 PreparedStatement的set方
法來賦值。
#{} 可以有效的防止SQL注入,提高系統(tǒng)安全性;${} 不能防止SQL 注入
#{} 的變量替換是在數(shù)據(jù)庫系統(tǒng)中; ${} 的變量替換是在數(shù)據(jù)庫系統(tǒng)外
14- Mybatis 如何獲取生成的主鍵
我知道的有二種方式
-
在insert標(biāo)簽上, 使用
useGeneratedKeys="true"和keyProperty="userId" -
在insert表內(nèi)部, 使用
selectKey標(biāo)簽 , 里面使用select last_insert_id()查詢生成的ID返回
15- 當(dāng)實體類中的屬性名和表中的字段名不一樣 ,怎么辦
第1種: 通過在查詢的SQL語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。
第2種: 通過 ResultMap來映射字段名和實體類屬性名
16- Mybatis如何實現(xiàn)多表查詢
Mybatis是新多表查詢的方式也有二種 :
第一種是 : 編寫多表關(guān)聯(lián)查詢的SQL語句 , 使用ResultMap建立結(jié)果集映射 , 在ResultMap中建立多表結(jié)果集映射
的標(biāo)簽有association和collection
<resultMap id="Account_User_Map" type="com.heima.entity.Account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user">
<id property="id" column="uid"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
<!--public Account findByIdWithUser(Integer id);-->
<select id="findByIdWithUser" resultMap="Account_User_Map">
select a.*, username, birthday, sex, address from account a , user u where a.UID = u.id and a.ID = #{id} ;
</select>
第二種是 : 將多表查詢分解為多個單表查詢, 使用ResultMap表的子標(biāo)簽association和collection標(biāo)簽的
select屬性指定另外一條SQL的定義去執(zhí)行, 然后執(zhí)行結(jié)果會被自動封裝
<resultMap id="Account_User_Map" type="com.heima.entity.Account" autoMapping="true">
<id property="id" column="id"></id>
<association property="user" select="com.heima.dao.UserDao.findById" column="uid" fetchType="lazy"></association>
</resultMap>
<!--public Account findByIdWithUser(Integer id);-->
<select id="findByIdWithUser" resultMap="Account_User_Map">
select * from account where id = #{id}
</select>
17-Mybatis都有哪些動態(tài)sql?能簡述一下動 態(tài)sql的執(zhí)行原理嗎?
Mybatis動態(tài)sql可以讓我們在Xml映射文件內(nèi),以標(biāo)簽的形式編寫動態(tài)sql,完成邏輯判斷和動態(tài) 拼接sql的功能,
Mybatis提供了9種動態(tài)sql標(biāo)簽 trim|where|set|foreach|if|choose|when|otherwise|bind。
其執(zhí)行原理為,使用OGNL從sql參數(shù)對象中計算表達(dá)式的值,根據(jù)表達(dá)式的值動態(tài)拼接sql,以此 來完成動態(tài)sql的功
能。
18- Mybatis是否支持延遲加載?
Mybatis僅支持association關(guān)聯(lián)對象和collection關(guān)聯(lián)集合對象的延遲加載,association指的就是 一對一,
collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲加載
lazyLoadingEnabled=true|false。
19- 如何使用Mybatis實現(xiàn)批量插入 ?
使用foreach標(biāo)簽 , 它可以在SQL語句中進行迭代一個集合。foreach標(biāo)簽的屬性主 要有item,index,collection,
open,separator,close。
- collection : 代表要遍歷的集合 ,
- item?? 表示集合中每一個元素進行迭代時的別名,隨便起的變量名;
- index?? 指定一個名字,用于表示在迭代過程中,每次迭代到的位置,不常用;
- open?? 表示該語句以什么開始
- separator 表示在每次進行迭代之間以什么符號作為分隔符
- close?? 表示以什么結(jié)束
20- Mybatis 批量插入是否能夠返回主鍵
可以, 返回的主鍵在傳入集合的每個對象屬性中封裝的
21- Mybatis的一級、二級緩存 ?
一級緩存: 基于SqlSession級別的緩存 , 默認(rèn)開啟
二級緩存 : 基于SqlSessionFactory的NameSpace級別緩存 , 默認(rèn)沒有開啟, 需要手動開啟
# 配置cacheEnabled為true
<settings>...
<!-- 開啟二級緩存 -->
<setting name="cacheEnabled" value="true"/>
...
</settings>
# 在映射配置文件中配置cache相關(guān)配置
<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024">
</cache>

浙公網(wǎng)安備 33010602011771號