今天這篇文章主要是為大家整理了一些Java面試框架類內(nèi)容供大家參考學(xué)習(xí),具體Java面試題框架主題內(nèi)容如下。
(1)SSH三大框架的概述
SSH為struts+spring+hibernate的一個集成框架,是目前較流行的一種Web應(yīng)用程序開源框架。
集成SSH框架的系統(tǒng)從職責(zé)上分為四層:表示層、業(yè)務(wù)邏輯層、數(shù)據(jù)持久層和域模塊層(實(shí)體層),以幫助開發(fā)人員在短期內(nèi)搭建結(jié)構(gòu)清晰、可復(fù)用性好、維護(hù)方便的Web應(yīng)用程序。
struts標(biāo)簽庫:Struts2默認(rèn)的表達(dá)式語言是OGNL(Object-Graph Navigation Language),通過它可以存取對象的任意屬性、調(diào)用對象的方法、遍歷整個對象的結(jié)構(gòu)圖、實(shí)現(xiàn)字段類型轉(zhuǎn)換等功能。
JSP:HTML文件中插入Java程序段和JSP標(biāo)記。
web.xml:Struts2核心過濾器和監(jiān)聽器
struts.xml:管理應(yīng)用中的Action映射,及Action處理結(jié)果和物理資源之間的映射。
applicationContext.xml:整合了struts和Hibernate。
.hbm.xml:O/R Mapping(Object Relational Mapping)映射文件,實(shí)體和表的映射關(guān)系通過XML來描述的文件。在項(xiàng)目啟動的時候加載到內(nèi)存中。
PO:Persistent Object,持久化對象
整體的調(diào)用關(guān)系:JSP–Action–Service–DAO–PO–數(shù)據(jù)庫
(2)什么是struts2
Struts2是一個基于MVC設(shè)計(jì)模式的Web應(yīng)用控制層框架,功能就是完成jsp頁面和后臺java代碼的傳值和跳轉(zhuǎn)。
Struts2的運(yùn)行原理
1:當(dāng)前臺發(fā)送一個以規(guī)定后綴相同的請求時如:.action struts核心控制器會對其進(jìn)行過濾攔截核心控制器StrutsPrepareAndExecuteFilter
2:核心控制器攔截請求后會根據(jù)請求的路徑找到對應(yīng)的java代碼,通過路徑中的類名(!前的部分)匹配struts.xml中action標(biāo)簽中的name屬性來找到具體訪問的類,!后的部分匹配類中的方法名
3:當(dāng)java類中完成處理邏輯會返回一個字符串,根據(jù)字符串匹配struts.xml中result標(biāo)簽的name屬性,然后跳轉(zhuǎn)到result標(biāo)簽內(nèi)容指定的頁面。
(3)Spring
簡單來說,spring是一個輕量級的控制反轉(zhuǎn)(IOC)和面向切面(AOP)的容器框架。
◆輕量——從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架可以在一個大小只有1MB多的JAR文件里發(fā)布。并且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應(yīng)用中的對象不依賴于Spring的特定類。
◆控制反轉(zhuǎn)——Spring通過一種稱作控制反轉(zhuǎn)(IOC)的技術(shù)促進(jìn)了松耦合。當(dāng)應(yīng)用了IOC,一個對象依賴的其它對象會通過被動的方式傳遞進(jìn)來,而不是這個對象自己創(chuàng)建或者查找依賴對象。這也是說spring是非侵入式的,動態(tài)注入對象,讓一個對象的創(chuàng)建不用new,可以自動生成,這就是利用JAVA里的反射,反射其實(shí)就是在運(yùn)行時動態(tài)的去創(chuàng)建、調(diào)用對象及其方法,spring就是在運(yùn)行時,跟xml spring的配置文件來動態(tài)的創(chuàng)建對象,和調(diào)用對象里面的方法反射技術(shù)的使用使得我們不再像原始的工廠方法模式那樣創(chuàng)建對象。反射可以非常靈活的根據(jù)類的名稱創(chuàng)建一個對象。所以spring只使用了Prototype和Singleton這兩個基本的模式。
◆面向切面——Spring提供了面向切面編程的豐富支持,允許通過分離應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)級服務(wù)(例如審計(jì)(auditing)和事務(wù)(transaction)管理,主要實(shí)現(xiàn)對事務(wù)的管理)進(jìn)行內(nèi)聚性的開發(fā),其機(jī)理來自于代理模式。應(yīng)用對象只實(shí)現(xiàn)它們應(yīng)該做的——完成業(yè)務(wù)邏輯——僅此而已。它們并不負(fù)責(zé)(甚至是意識)其它的系統(tǒng)級關(guān)注點(diǎn),例如日志或事務(wù)支持。
◆容器——Spring含并管理應(yīng)用對象的配置和生命周期,在這個意義上它是一種容器,你可以配置你的每個bean如何被創(chuàng)建——基于一個可配置原型(prototype),你的bean可以創(chuàng)建一個單獨(dú)的實(shí)例或者每次需要時都生成一個新的實(shí)例——以及它們是如何相互關(guān)聯(lián)的。然而,Spring不應(yīng)該被混同于傳統(tǒng)的重量級的EJB容器,它們經(jīng)常是龐大與笨重的,難以使用。Spring是一個容器,凡是在容器里的對象才會有Spring所提供的這些服務(wù)和功能。凡是在spring的配置文件里面配置了,才能被spring管理;并享用spring提供的服務(wù)。
◆框架——Spring可以將簡單的組件配置、組合成為復(fù)雜的應(yīng)用。在Spring中,應(yīng)用對象被聲明式地組合,典型地是在一個XML文件里。Spring也提供了很多基礎(chǔ)功能(事務(wù)管理、持久化框架集成等等),將應(yīng)用邏輯的開發(fā)留給了你。所有Spring的這些特征使你能夠編寫更干凈、更可管理、并且更易于測試的代碼。它們也為Spring中的各種模塊提供了基礎(chǔ)支持。
談Spring這個問題的時候,首先Spring中最為重要的無非就是IOC和AOP,而對IOC來講,你講一下IOC的定義,IOC就是說對象本身的創(chuàng)建不依賴應(yīng)用本身,而是依賴于外部容器,如果沒有IOC那么我們在我們的業(yè)務(wù)類,要調(diào)用DAO的方法,那么不得不做的一個動作就是創(chuàng)建一個DAO的實(shí)現(xiàn)類的實(shí)例,而創(chuàng)建這個對象本身是跟業(yè)務(wù)無關(guān)的,而這樣違反了“高內(nèi)聚,低耦合”,使類與類的聯(lián)系非常緊密了。即使你不用new,你使用工廠模式,使用單利模式,也跟上面說的效果是一樣的,而Spring本身就是一個大工廠,他幫我們造對象,幫我們管理bean對象,它幫我們注入我們所需的bean對象,這樣對于以后的維護(hù)來講,變的更為方便,也把與業(yè)務(wù)本身無關(guān)的東西提取出來了。體現(xiàn)了低耦合。而AOP本身就是一種思想,意為面向切面編程,而Spring對AOP做了部分實(shí)現(xiàn),(舉例說明)如果沒有AOP,比如我們開發(fā)的系統(tǒng)中有發(fā)郵件,寫日志,可想而知,系統(tǒng)中發(fā)郵件,寫日志絕對的不是在一個地方用到,那么怎么辦,肯定是在業(yè)務(wù)中寫著重復(fù)的代碼,而且干著與業(yè)務(wù)無關(guān)的事情,也就是說讓發(fā)郵件,寫日志跟業(yè)務(wù)一起混合在一起,那么這樣肯定是不合理的。那么該怎么辦,因此Spring提供了AOP,在你想寫日志的方法給你切開,加入日志的操作,剛剛說spring是大工廠,那么對于spring的AOP來講,我更加喜歡把它比喻成化妝師,只有你讓spring幫你化妝,就能達(dá)到你意想不到的效果,總的來講spring的AOP技術(shù),他幫我們做很多與業(yè)務(wù)無關(guān)的操作,讓業(yè)務(wù)層次更加清晰。
Spring AOP事務(wù)的描述:
在applicationContent.xml里通過aop:config里面先設(shè)定一個表達(dá)式,設(shè)定對service里那些方法如:對add*,delete*,update*等開頭的方法進(jìn)行事務(wù)攔截。我們需要配置事務(wù)的傳播(propagation=“REQUIRED”)特性,通常把增,刪,改以外的操作需要配置成只讀事務(wù)(read-only=“true”).只讀事務(wù)可以提高性能。之后引入tx:advice,在tx:advice引用transactionManager(事務(wù)管理),在事務(wù)管理里再引入sessionFactory,sessionFactory注入dataSource,最后通過aop:config引入txAdvice。
事物的7種傳播特性
opropagation_requierd:如果當(dāng)前沒有事務(wù),就新建一個事務(wù),如果已存在一個事務(wù)中,加入到這個事務(wù)中,這是最常見的選擇。
opropagation_supports:支持當(dāng)前事務(wù),如果沒有當(dāng)前事務(wù),就以非事務(wù)方法執(zhí)行。
opropagation_mandatory:使用當(dāng)前事務(wù),如果沒有當(dāng)前事務(wù),就拋出異常。
opropagation_required_new:新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。
opropagation_not_supported:以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。
opropagation_never:以非事務(wù)方式執(zhí)行操作,如果當(dāng)前事務(wù)存在則拋出異常。
opropagation_nested:如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則執(zhí)行與propagation_required類似的操作
Spring默認(rèn)的事物傳播行為是propagation_requierd
(4)Hibernate
1:hibernate是什么
Hibernate是一個開放源代碼的對象關(guān)系映射框架,它對JDBC進(jìn)行了非常輕量級的對象封裝,它將POJO與數(shù)據(jù)庫表建立映射關(guān)系,是一個全自動的orm框架,hibernate可以自動生成SQL語句,自動執(zhí)行,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數(shù)據(jù)庫。Hibernate可以應(yīng)用在任何使用JDBC的場合
是基于JDBC使用面向?qū)ο蠓庋b而來的ORM持久層框架/數(shù)據(jù)庫中間件
2:什么是ORM?
O:Object:對象,
R:Relation:關(guān)系型數(shù)據(jù)庫;-->oracle,mysql,
M:Mapping:映射;就是一個xml的配置文件,
通過配置文件將對象和關(guān)系型數(shù)據(jù)庫連接起來實(shí)現(xiàn)我們通過操作對象的形式來操作數(shù)據(jù)庫。
3:hibernate和jdbc的區(qū)別
1.jdbc和hibernate都是數(shù)據(jù)庫中間件/持久層框架用來操作數(shù)據(jù)庫
2.hibernate是基于jdbc封裝而來
不同
JDBC
1.不能跨數(shù)據(jù)庫不同的數(shù)據(jù)庫使用不同鏈接驅(qū)動jar
2.使用sql語句操作數(shù)據(jù)庫
3.查詢時結(jié)果集需要手動遍歷封裝到j(luò)ava對象
4.執(zhí)行效率高開發(fā)效率低
Hibernate
1.能夸數(shù)據(jù)庫通過方言配置可以切換不同的數(shù)據(jù)庫語言
2.通過對象操作數(shù)據(jù)庫或者是HQL語句不管是通過對象還是HQL語句最終都會變成sql語句執(zhí)行
3.查詢時hibernate通過配置的關(guān)系直接返回java對象通過反射機(jī)制自動封裝對象,反射是很耗費(fèi)資源的
4.執(zhí)行效率低開發(fā)效率高
4:Hibernate核心類
Configuration代表hibernate配置信息的類
hibernate啟動時通過Configuration類讀取數(shù)據(jù)庫配置和映射關(guān)系
configure()方法加載配置文件
buildSessionFactory()構(gòu)建session工廠
SessionFactory會話工廠可以認(rèn)為是jdbc中的Connection對象openSession()打開一個回話
Session會話類
操作數(shù)據(jù)庫的save(對象)新增
get(類型,主鍵)只返回一條數(shù)據(jù)必須根據(jù)主鍵查詢
load(類型,主鍵)只返回一條數(shù)據(jù)必須根據(jù)主鍵查詢
delete(對象)根據(jù)對象的id刪除記錄
update(對象)根據(jù)對象的id修改記錄
saveOrUpdate(對象)對象id不存在執(zhí)行新增存在執(zhí)行修改
Transaction事務(wù)
transaction.commit();提交事務(wù)
transaction.rollback();回滾事務(wù)
Query書寫執(zhí)行HQL語句
獲得query
session.cre=ateQuery(“hql可以有占位符號”);
1.替換占位符號
query.setParamenter(“下標(biāo)從零開始,值”);
2.查詢List結(jié)果集
query.list();返回多條數(shù)據(jù)以List集合的形式
3.獲得唯一結(jié)果集(必須確定結(jié)果集唯一才能使用)
uniqueResult();只返回一個Object對象
4.執(zhí)行修改數(shù)據(jù)的操作
executeUpdate();執(zhí)行刪除新增修改的語句
5:主鍵生成策略
increment:適用于short,int,long作為主鍵,不是使用的數(shù)據(jù)庫自動增長,是先查詢數(shù)據(jù)庫中的id值,然后在的基礎(chǔ)上加一,然后賦值。
identity:自動遞增,只適用于自動遞增的數(shù)據(jù)庫。(oracle不能使用)。
sequence:序列,只適用于有序列的數(shù)據(jù)庫。(適用與oracle)。
uuid:適用于char,varchar類型的主鍵。
native:本地的。使用數(shù)據(jù)庫本身的方式,
(比如oracle是使用序列,而mysql則使用遞增)。
6:Hibernate緩存
緩存是介于應(yīng)用程序和物理數(shù)據(jù)源之間,其作用是為了降低應(yīng)用程序?qū)ξ锢頂?shù)據(jù)源訪問的頻次,從而提高了應(yīng)用的運(yùn)行性能。
緩存內(nèi)的數(shù)據(jù)是對物理數(shù)據(jù)源中的數(shù)據(jù)的復(fù)制,應(yīng)用程序在運(yùn)行時從緩存讀寫數(shù)據(jù),在特定的時刻或事件會同步緩存和物理數(shù)據(jù)源的數(shù)據(jù)。
一級緩存自動開啟的是session的緩存無需配置自動使用
二級緩存是需要配置第三方緩存例如OScache是sessionFactory的緩存
三級緩存/查詢緩存無需配置自動使用
7:Hibernate查詢的策略
是先從緩存查詢對象如果緩存中沒有對應(yīng)條件的對象再發(fā)送sql語句查詢數(shù)據(jù)庫,如果緩存中存在符合條件的對象就是用緩存中的數(shù)據(jù),從而降低查詢效率。
8:get和load的區(qū)別
1.get當(dāng)查詢的id在緩存和數(shù)據(jù)庫中都不存在的話返回null
2.load當(dāng)查詢的id在緩存和數(shù)據(jù)庫中都不存在的話會發(fā)生異常ObjectNotFoundException
load可以執(zhí)行懶加載的操作
懶加載功能:當(dāng)我們查詢一個hibernate對象時只獲得對象的id
當(dāng)使用到對象的其他屬性時再去數(shù)據(jù)庫查詢其他的信息
9:Hibernate對象狀態(tài)
Hibernate中對象有三種狀態(tài):臨時狀態(tài)(Transient)、持久狀態(tài)(Persistent)、游離狀態(tài)(Detached)。
臨時狀態(tài):剛剛使用new語句創(chuàng)建,還沒有被持久化,不處于Session的緩存中。處于臨時狀態(tài)的狀態(tài)的Java對象被稱為臨時對象。
持久化狀態(tài):已經(jīng)被持久化,加入到Session的緩存中。處于持久化狀態(tài)的Java對象被稱為持久化對象。
游離狀態(tài)/托管狀態(tài):已經(jīng)被持久化,但不處于session的緩存中。處于游離狀態(tài)的Java對象被稱為游離對象。
10:為什么使用hibernate
1)、對JDBC訪問數(shù)據(jù)庫的代碼做了封裝,大大簡化了數(shù)據(jù)訪問層繁瑣的重復(fù)性代碼。
2)、Hibernate是一個優(yōu)秀的ORM實(shí)現(xiàn)。他很大程度的簡化DAO層的編碼,將軟件開發(fā)人員從大量相同的數(shù)據(jù)持久層相關(guān)編程中解放出來,使開發(fā)更對象化了。
3)、移植性好,支持各種數(shù)據(jù)庫,如果換個數(shù)據(jù)庫只要在配置文件中變換配置就可以了,不用改變hibernate代碼。
4)、支持透明持久化,因?yàn)閔ibernate操作的是純粹的(pojo)java類,沒有實(shí)現(xiàn)任何接口,沒有侵入性。所以說它是一個輕量級框架。
1:談?wù)勀銓ibernate的理解。
面向?qū)ο笤O(shè)計(jì)的軟件內(nèi)部運(yùn)行過程可以理解成就是在不斷創(chuàng)建各種新對象、建立對象之間的關(guān)系,調(diào)用對象的方法來改變各個對象的狀態(tài)和對象消亡的過程,不管程序運(yùn)行的過程和操作怎么樣,本質(zhì)上都是要得到一個結(jié)果,程序上一個時刻和下一個時刻的運(yùn)行結(jié)果的差異就表現(xiàn)在內(nèi)存中的對象狀態(tài)發(fā)生了變化。
2.為了在關(guān)機(jī)和內(nèi)存空間不夠的狀況下,保持程序的運(yùn)行狀態(tài),需要將內(nèi)存中的對象狀態(tài)保存到持久化設(shè)備和從持久化設(shè)備中恢復(fù)出對象的狀態(tài),通常都是保存到關(guān)系數(shù)據(jù)庫來保存大量對象信息。從Java程序的運(yùn)行功能上來講,保存對象狀態(tài)的功能相比系統(tǒng)運(yùn)行的其他功能來說,應(yīng)該是一個很不起眼的附屬功能,java采用jdbc來實(shí)現(xiàn)這個功能,這個不起眼的功能卻要編寫大量的代碼,而做的事情僅僅是保存對象和恢復(fù)對象,并且那些大量的jdbc代碼并沒有什么技術(shù)含量,基本上是采用一套例行公事的標(biāo)準(zhǔn)代碼模板來編寫,是一種苦活和重復(fù)性的。
3.通過數(shù)據(jù)庫保存java程序運(yùn)行時產(chǎn)生的對象和恢復(fù)對象,其實(shí)就是實(shí)現(xiàn)了java對象與關(guān)系數(shù)據(jù)庫記錄的映射關(guān)系,稱為ORM(即Object Relation Mapping),人們可以通過封裝JDBC代碼來實(shí)現(xiàn)了這種功能,封裝出來的產(chǎn)品稱之為ORM框架,Hibernate就是其中的一種流行ORM框架。使用Hibernate框架,不用寫JDBC代碼,僅僅是調(diào)用一個save方法,就可以將對象保存到關(guān)系數(shù)據(jù)庫中,僅僅是調(diào)用一個get方法,就可以從數(shù)據(jù)庫中加載出一個對象。
4.使用Hibernate的基本流程是:配置Configuration對象、產(chǎn)生SessionFactory、創(chuàng)建session對象,啟動事務(wù),完成CRUD操作,提交事務(wù),關(guān)閉session。
5.使用Hibernate時,先要配置hibernate.cfg.xml文件,其中配置數(shù)據(jù)庫連接信息和方言等,還要為每個實(shí)體配置相應(yīng)的hbm.xml文件,hibernate.cfg.xml文件中需要登記每個hbm.xml文件。
6.在應(yīng)用Hibernate時,重點(diǎn)要了解Session的緩存原理,級聯(lián),延遲加載和hql查詢。
(5)SSH整合
在項(xiàng)目中首先是通過在web.xml中配置strtus2的前端控制器StrutsPrepareAndExecuteFilter加載struts.xml
配置文件并對指定的后綴名進(jìn)行攔截,并且通過配置spring的監(jiān)聽器contextLoadListener
加載spring的相關(guān)配置文件如
spring-service.xml,spring-dao.xml,spring-common.xml,
之后新建控制層的類繼承于BaseAction,而BaseAction繼承于ActionSupport,
在BaseAction中封裝了常用的方法如getRealPath(),outJson()等,
之后控制層注入service層,service層注入dao,dao層繼承于HibernateDaoSupport
并注入spring-common.xml中配置的sessionFactory,sessionFactory注入dataSource連接數(shù)據(jù)庫,
注入hibernate.cfg.xml從而加載hbm.xml文件,
除此之外還通過Spring中的Aop配置了事務(wù)并且通過切點(diǎn)表達(dá)式對Servcie層代碼進(jìn)行控制。
(6)總結(jié)
在SSH中使用Struts作為系統(tǒng)的整體基礎(chǔ)架構(gòu),負(fù)責(zé)MVC的分離,在Struts框架的模型部分,控制業(yè)務(wù)跳轉(zhuǎn),利用Hibernate框架對持久層提供支持,Spring做支持,支持struts和hibernate。具體做法是:用面向?qū)ο蟮姆治龇椒ǜ鶕?jù)需求提出一些模型,將這些模型實(shí)現(xiàn)為基本的Java對象,然后編寫基本的DAO(Data Access Objects)接口,并給出Hibernate的DAO實(shí)現(xiàn),采用Hibernate架構(gòu)實(shí)現(xiàn)的DAO類來實(shí)現(xiàn)Java類與數(shù)據(jù)庫之間的轉(zhuǎn)換和訪問,最后由Spring做支持,支持struts和hibernate。其實(shí)ssh框架最主要的本質(zhì)是:“高內(nèi)聚、低耦合”。
SSH框架優(yōu)點(diǎn):
1.spring管理對象的實(shí)例化,把對象的創(chuàng)建和獲取放到外部,更加的靈活方便。
2.Hibernate避免了JDBC連接數(shù)據(jù)庫的冗余繁雜。
3.各層分工明細(xì),實(shí)現(xiàn)了各層之間的解耦,代碼更加靈活。
2:SSM框架
(1)SSM框架概述
SSM框架是spring MVC,spring和mybatis框架的整合,是標(biāo)準(zhǔn)的MVC模式,將整個系統(tǒng)劃分為表現(xiàn)層,controller層,service層,DAO層四層
使用spring MVC負(fù)責(zé)請求的轉(zhuǎn)發(fā)和視圖管理
spring實(shí)現(xiàn)業(yè)務(wù)對象管理,mybatis作為數(shù)據(jù)對象的持久化引擎
(2)SpringMVC
1:介紹
Spring MVC是基于組件技術(shù)的,全部的應(yīng)用對象,無論是控制器和視圖,還是業(yè)務(wù)對象之類的都是java組件,并且spring mvc不依賴于Servlet API,可以任意使用任何視圖技術(shù),支持各種請求資源的映射策略,并且spring mvc是易于擴(kuò)展的。
2:運(yùn)行原理
Spring mvc的運(yùn)行原理是從一個HTTP請求開始:Tomcat在啟動時加載解析web.xml,找到spring mvc的前端總控制器DispatcherServlet,并且通過DispatcherServlet來加載相關(guān)的配置文件信息。DispatcherServlet接收到客戶端請求,找到對應(yīng)HandlerMapping,根據(jù)映射規(guī)則,找到對應(yīng)的處理器(Handler)。調(diào)用相應(yīng)處理器中的處理方法,處理該請求后,會返回一個ModelAndView。DispatcherServlet根據(jù)得到的ModelAndView中的視圖對象,找到一個合適的ViewResolver(視圖解析器),根據(jù)視圖解析器的配置,DispatcherServlet將要顯示的數(shù)據(jù)傳給對應(yīng)的視圖,最后顯示給用戶。
3:常用注解
我在使用spring mvc的時候用到了很多注解,比如RequestMapping在類面前定義,將url和類綁定。在方法面前定義,則將url和類的方法進(jìn)行綁定。還有RequestParam一般用于將指定的請求參數(shù)付給方法中的形參。
Responsebody是將對象轉(zhuǎn)換為json格式進(jìn)行傳輸。
Autowired和Resource注解的作用都是為了進(jìn)行屬性注入,Autowired默認(rèn)是按照類型進(jìn)行匹配的是spring提供的注解,Resource默認(rèn)是按照名字進(jìn)行匹配,它是java提供的注解,我一直在項(xiàng)目中使用的是Autowired注入。
4:注意
spring和MVC是父子容器關(guān)系,spring是父容器,MVC是子容器.子能訪問父中的對象,而父卻不能訪問子容器中的對象.基于這點(diǎn)我們還可以深入一下,不用spring容器,只用mvc容器是可以的,因?yàn)樗锩婵梢酝瑫r掃描controller層.service層.dao層的注解.而不用mvc容器,只用spring容器是不可以的,下面我們來查看具體原因,翻看源碼,從SpringMVC的DispatcherServlet開始往下找,我們發(fā)現(xiàn)SpringMVC初始化時,會尋找SpringMVC容器中的所有使用了Controller注解的Bean,來確定其是否是一個handler。springMVC容器中并沒有注冊帶有Controller注解的Bean,而是把所有帶有Controller注解的Bean都注冊在Spring這個父容器中了,所以springMVC找不到處理器,不能進(jìn)行跳轉(zhuǎn)。springmvc中處理器映射器的底層原理,是一個map(“url路徑”,controller的方法)。通過攔截請求得到相應(yīng)的url路徑,然后從map中找對象的controller方法。
5:在springmvc和spring都有注解掃描的前提下,不能將事務(wù)配置在Controller層?
因?yàn)槭聞?wù)管理器是配置在spring容器中的,如果將事務(wù)配置在Controller層的話,spring容器就訪問不了springmvc子容器,進(jìn)而無法訪問到事務(wù)對象。進(jìn)而導(dǎo)致事務(wù)失效.
(3)Mybatis
1:介紹
MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優(yōu)秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數(shù)的手工設(shè)置以及對結(jié)果集的檢索封裝。MyBatis可以使用簡單的XML或注解用于配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數(shù)據(jù)庫中的記錄。
2:Mybatis的緩存分為一級緩存和二級緩存。
一級緩存是sqlSession級別的緩存,是基于HashMap的本地緩存,不同的sqlsession之間的緩存數(shù)據(jù)區(qū)域互不影響,一級緩存的作用于是sqlsession范圍,當(dāng)同一個sqlsession執(zhí)行兩次相同的SQL語句時,次執(zhí)行完后會將數(shù)據(jù)庫中插敘到的數(shù)據(jù)寫到緩存,第二次查詢從緩存中獲取,不用去查詢數(shù)據(jù)庫。當(dāng)sqlsession執(zhí)行insert,update,delete操作并提交到數(shù)據(jù)庫時,會先清空緩存,緩存中的數(shù)據(jù)是最新數(shù)據(jù)。mybatis默認(rèn)開啟的是一級緩存。
二級緩存是mapper級別的緩存,同樣是基于HashMap進(jìn)行存儲,多個sqlsession可以共用二級緩存,其作用域是mapper的同一個namespace。不同色sqlsession兩次執(zhí)行相同的namespace下的相同的SQL語句時,會執(zhí)行相同的SQL,第二次查詢只會查詢次查詢時讀取數(shù)據(jù)庫后寫到緩存的數(shù)據(jù),不會再去數(shù)據(jù)庫查詢。
3:jdbc,mybatis,hibernate的區(qū)別
Hibernate屬于全自動,mybatis屬于半自動,Jdbc屬于手動,從開發(fā)效率上講hibernate較高,mybatis居中,jdbc較低,從執(zhí)行效率上講hibernate較低,mybatis居中,jdbc較高,因?yàn)閖dbc是手工寫sql語句,程序員對sql的控制能力更大,可以根據(jù)業(yè)務(wù)需要進(jìn)行優(yōu)化,而mybatis雖然也可以對sql進(jìn)行優(yōu)化,但是他里面將resultset封裝為實(shí)體的過程中采用了反射機(jī)制所以一定程度上影響了性能,但是Mybatis可以支持mapping映射,直接寫一個mapper接口,交給spring來管理,只要接口的方法名和sql的id保持一致,就可以輕松的調(diào)用方法。而hibernate因?yàn)楦叨确庋b所以開發(fā)效率相對較高,但正因?yàn)檫@個原因,所以程序員在對sql語句的控制和優(yōu)化方面相對比較弱,而且在將resultset封裝成實(shí)體的過程中也采用了反射機(jī)制,所以在性能方面比起MyBatis較低。
3:JDBC
JDBC:是java data base connectivity縮寫。用java連接數(shù)據(jù)庫
Jdbc作用:
(1)建立與數(shù)據(jù)庫的連接
(2)發(fā)送sql語句到數(shù)據(jù)庫
(3)處理返回的結(jié)果集
如何使用JDBC?
(1)準(zhǔn)備ojdbc版本號.jar(比如ojdbc14.jar)
(2)jar是什么?jar就是封裝好相應(yīng)功能代碼的類,通過jar的導(dǎo)入,可以讓程序直接
(3)使用jar中的方法、屬性等
使用jdbc操作數(shù)據(jù)庫:
(1)導(dǎo)jar
(2)加載驅(qū)動,為數(shù)據(jù)庫連接做準(zhǔn)備Class.forName(“oracle.jdbc.driver.OracleDriver”)
(3)準(zhǔn)備用戶名,口令,等連接數(shù)據(jù)庫
DriverManager.getConnection(“jdbc:oracle:thin:localhost:1521:xe”,“xxx”,“xxx”)
(4)寫sql語句
(5)創(chuàng)建數(shù)據(jù)庫操作對象
(6)執(zhí)行sql語句
(7)關(guān)閉連接,釋放資源
Class.forName的作用?為什么要用?
按參數(shù)中指定的字符串形式的類名去搜索并加載相應(yīng)的類,如果該類字節(jié)碼已經(jīng)被加載過,則返回代表該字節(jié)碼的Class實(shí)例對象,否則,按類加載器的委托機(jī)制去搜索和加載該類,如果所有的類加載器都無法加載到該類,則拋出ClassNotFoundException。加載完這個Class字節(jié)碼后,接著就可以使用Class字節(jié)碼的newInstance方法去創(chuàng)建該類的實(shí)例對象了。
有時候,我們程序中所有使用的具體類名在設(shè)計(jì)時(即開發(fā)時)無法確定,只有程序運(yùn)行時才能確定,這時候就需要使用Class.forName去動態(tài)加載該類,這個類名通常是在配置文件中配置的,例如,spring的ioc中每次依賴注入的具體類就是這樣配置的,jdbc的驅(qū)動類名通常也是通過配置文件來配置的,以便在產(chǎn)品交付使用后不用修改源程序就可以更換驅(qū)動類名。
4:微服務(wù)框架
4.1:什么是微服務(wù)?
簡而言之,微服務(wù)架構(gòu)風(fēng)格這種開發(fā)方法,是以開發(fā)一組小型服務(wù)的方式來開發(fā)一個獨(dú)立的應(yīng)用系統(tǒng)的。其中每個小型服務(wù)都運(yùn)行在自己的進(jìn)程中,并經(jīng)常采用HTTP資源API這樣輕量的機(jī)制來相互通信。這些服務(wù)圍繞業(yè)務(wù)功能進(jìn)行構(gòu)建,并能通過全自動的部署機(jī)制來進(jìn)行獨(dú)立部署。這些微服務(wù)可以使用不同的語言來編寫,并且可以使用不同的數(shù)據(jù)存儲技術(shù)。對這些微服務(wù)我們僅做最低限度的集中管理。
4.2:微服務(wù)具備的特性?
每個微服務(wù)可獨(dú)立運(yùn)行在自己的進(jìn)程里;
一系列獨(dú)立運(yùn)行的微服務(wù)共同構(gòu)建起了整個系統(tǒng);
每個服務(wù)為獨(dú)立的業(yè)務(wù)開發(fā),一個微服務(wù)一般完成某個特定的功能,比如:訂單管理、用戶管理等;
微服務(wù)之間通過一些輕量的通信機(jī)制進(jìn)行通信,例如通過REST API或者RPC的方式進(jìn)行調(diào)用。
4.3:微服務(wù)優(yōu)點(diǎn)
易于開發(fā)和維護(hù),啟動較快,局部修改容易部署,技術(shù)棧不受限,按需伸縮,DevOps
4.4:微服務(wù)帶來的挑戰(zhàn)
運(yùn)維要求較高,分布式的復(fù)雜性,接口調(diào)整成本高,重復(fù)勞動
4.5:微服務(wù)設(shè)計(jì)原則
單一職責(zé)原則,服務(wù)自治原則,輕量級通信原則,接口明確原則
1:SpringBoot
Springboot框架在使用過程中也是比較簡單的,我們當(dāng)時整合mybatis后,直接啟動就可以使用了。整合mybatis也是比較簡單的,首先在pom.xml中,配置加載spring-boot-starter-parent父類jar,再引入spring-boot-starter配置。如果是搭建了web項(xiàng)目的話,還需要引入spring-boot-data-web jar,當(dāng)時我們是整合mybatis持久層框架,所以需要導(dǎo)入mybatis-spring-boot-starter和mysql-connecter-java整合,這樣就配置完成了。
另外項(xiàng)目中鏈接數(shù)據(jù)源有兩種方式,通過application.properties文件,或者application.yml文件,配置文件中必須安裝數(shù)據(jù)庫鏈接設(shè)置。因?yàn)閟pringboot沒有配置文件,所有的加載都是通過注解來生效的,使用的注解也比較多。
項(xiàng)目啟動的時候,使用SpringbootApplication放到啟動類上,直接執(zhí)行main方法就可以了,需要注意的是啟動類必須放到根下,這樣才能掃描到所有的類。我們還需要在控制層類上加上RestController注解(他相當(dāng)于是spring-mvc中的ResponseBody和Controller的結(jié)合),其他的注解和spring,spring-mvc的注解差不多了,比如Controller,RequestMapping,Service,PathVilable,Value等。用generator生成基本的增刪改查,復(fù)雜業(yè)務(wù)邏輯寫sql語句。
除了使用mybatis外,當(dāng)時我們還查到了springboot和jpa的整合,因?yàn)閖pa是不寫入sql的所以當(dāng)時就沒有使用,其實(shí)jpa使用起來挺簡單的,它是通過方法名來進(jìn)行對數(shù)據(jù)庫的操作,方法名的命名也是要有一定的規(guī)則的,dao層的接口需要繼承JpaRepositort<>。
在我們的項(xiàng)目中,考慮到相應(yīng)的節(jié)假日,網(wǎng)站活動的調(diào)整和頁面的渲染,所以采用了頁面靜態(tài)化的處理,我們用的是thymeleaf,其實(shí)也可以用freemarker,但是當(dāng)時我上網(wǎng)查了一下發(fā)現(xiàn)springboot整合thymeleaf比較好一些,所以就是用了thymeleaf。
Thymeleaf也是一款用于渲染xml、xhtml、html5內(nèi)容的模板引擎,其實(shí)跟valocity和freem
arker差不多,我在網(wǎng)上看了一下,thymeleaf和springboot整合還是很好用的,結(jié)構(gòu)很明顯,只是在對應(yīng)的標(biāo)簽中加上對應(yīng)的屬性就行了。如th:text設(shè)置文本內(nèi)容,th:href設(shè)置路徑,th:each循環(huán)數(shù)據(jù)等。
另外springboot還可以整合前段框架,有一個webjars官網(wǎng)可以直接找到前段配置的jar,直接引入到pom.xml中,讓前段框架也交給maven處理。
考慮到項(xiàng)目中要使用redis緩存服務(wù)器,我們當(dāng)時就整合了redis的主從配置5臺redis緩存服務(wù)器,還有哨兵機(jī)制。整合redis也比較簡單,也是在pom.xml中配置引入spring-boot-starter-data-redis,當(dāng)時我上網(wǎng)查了一下發(fā)現(xiàn),redis的1.4.7版本以上的需要引入spring-boot-starter-data-redis,而1.4.7版本以下的需要引入spring-boot-starter-redis。在application.properties文件中引入redis的相關(guān)配置,有端口號,ip地址,鏈接的數(shù)據(jù)庫等,直接配置就可以,只要redis服務(wù)器啟動,項(xiàng)目就可以使用了。當(dāng)時配置的時候,在啟動類上加EnableCaching注解,開啟緩存,這樣就可以在業(yè)務(wù)層實(shí)現(xiàn)類的方法上面加上Cacheable注解就可以使用了,這時候加載到方法后,首先去redis當(dāng)中取對應(yīng)數(shù)據(jù),如果有數(shù)據(jù),從緩存當(dāng)中獲取,如果沒有對應(yīng)數(shù)據(jù),再從數(shù)據(jù)庫中獲取數(shù)據(jù)。
當(dāng)時項(xiàng)目中也涉及到了多數(shù)據(jù)源的動態(tài)切換,在以前的項(xiàng)目中我們是使用spring的aop前置通知類實(shí)現(xiàn)數(shù)據(jù)源的動態(tài)切換,使用aop前置通知判斷到底是什么操作,如果是增刪改的操作,切換到主數(shù)據(jù)庫,如果是查詢操作,切換到從數(shù)據(jù)庫。現(xiàn)在使用springboot,實(shí)現(xiàn)動態(tài)切換數(shù)據(jù)源就比較簡單了。首先在application.properties文件中,配置多個數(shù)據(jù)源鏈接信息,使用的時候持久層接口通過結(jié)構(gòu)來區(qū)分到底走哪一個數(shù)據(jù)庫。寫一個配置類,在類上面加上,Configuration、MapperScan(basePackages=“”,sqlSessionTemplateRef=)
來設(shè)置配置,有幾個數(shù)據(jù)源,配置幾個配置類,然后在項(xiàng)目中通過業(yè)務(wù)邏輯類判斷到底走哪一個數(shù)據(jù)源。
另外,在項(xiàng)目中還配置了RabbitMQ消息隊(duì)列服務(wù)器,rabbitMQ是一個異步通信,與activeMQ相比,只是多了一個交換機(jī)的概念,它主要括,生產(chǎn)者、交換機(jī)、隊(duì)列、消費(fèi)者。它的配置也比較簡單,在pom.xml文件中加載對應(yīng)的jarspring-boot-starter-amqp,amqp是高級消息隊(duì)列協(xié)議,消息生產(chǎn)者調(diào)用AmqpTemplate rabbitTemplate,直接使用rabbitTempla.convertAndSend(message),發(fā)送到rabbitMQ中,通過交換機(jī)放到指定的隊(duì)列當(dāng)中,消費(fèi)者通過RabbitListener(queues=””)來監(jiān)聽對應(yīng)的隊(duì)列獲得信息,通過RabbitHandler注解來處理監(jiān)聽到的信息。
消息隊(duì)列,容易丟失隊(duì)列數(shù)據(jù)如何處理?:
解決方案:1.使用mongodb進(jìn)行數(shù)據(jù)的備份,電商業(yè)務(wù)下訂單時,會將所有的訂單先發(fā)送到消息隊(duì)列中,供后續(xù)監(jiān)聽獲得數(shù)據(jù)操作,為了防止訂單數(shù)據(jù)丟失問題,使用mongodb數(shù)據(jù)庫下訂單時,發(fā)送到rabbitmq的同時,會將訂單信息存入mongodb中備份,同時添加一個標(biāo)識字段0:未對賬,1:已對賬。
2.另外設(shè)置一個springboot定時器,每月月底定時查閱mongodb數(shù)據(jù)庫中一個月以前的數(shù)據(jù)信息,如果發(fā)現(xiàn)mongodb數(shù)據(jù)信息中有標(biāo)識還為0:未對賬的信息,會將該條信息重新加入到消息隊(duì)列中進(jìn)行處理)。剛才說道定時器了,我們也沒有使用Quartz定時器,我們使用的是springboot整合的定時器,直接在springboot啟動類上添加EnableScheduling就可以,然后再具體執(zhí)行的類上加上Scheduled(cron="*/6****?"),通過表達(dá)式來定義。另外還有發(fā)郵件功能,pom.xml配置文件中添加spring-boot-starter-mail.
Springboot整合mongodb也比較簡單,在pom.xml中加載配置spring-boot-starter-data-mongodb,然后在application.properties文件中配置mongodb數(shù)據(jù)庫鏈接信息,spring.data.mongodb.uri=mongodb://name:pass localhost:27017/test,如果有多個IP集群:spring.data.mongodb.uri=mongodb://user:pwd ip1:port1,ip2:port2/database創(chuàng)建實(shí)體dao,在持久層注入MongoTemplate模板,使用模板來實(shí)現(xiàn)對數(shù)據(jù)庫的ICUD操作。
如果是多個數(shù)據(jù)源,在pom.xml文件中加入lombok和spring-boot-autoconfigure引用。
Lombok-是一個可以通過簡單的注解形式來幫助我們簡化消除一些必須有但顯得很臃腫的Java代碼的工具,通過使用對應(yīng)的注解,可以在編譯源碼的時候生成對應(yīng)的方法。加上注解我們就不用手動寫getter\setter、構(gòu)建方式類似的代碼了。
spring-boot-autoconfigure-就是spring boot的自動化配置.
在application.properties文件中加入額外的數(shù)據(jù)源信息.配置不同路徑下使用不同的數(shù)據(jù)源,通過Configuration申明配置類EnableMongoRepositories注解指出的路徑,創(chuàng)建兩個庫分別對應(yīng)的對象和Repository借助lombok來構(gòu)建對象,到此,mongodb多數(shù)據(jù)源的使用已經(jīng)完成。
2:SpringCloud
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發(fā)便利性巧妙地簡化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開發(fā),如服務(wù)發(fā)現(xiàn)注冊、配置中心、消息總線、負(fù)載均衡、斷路器、數(shù)據(jù)監(jiān)控等,都可以用Spring Boot的開發(fā)風(fēng)格做到一鍵啟動和部署。Spring并沒有重復(fù)制造輪子,它只是將目前各家公司開發(fā)的比較成熟、經(jīng)得起實(shí)際考驗(yàn)的服務(wù)框架組合起來,通過Spring Boot風(fēng)格進(jìn)行再封裝屏蔽掉了復(fù)雜的配置和實(shí)現(xiàn)原理,最終給開發(fā)者留出了一套簡單易懂、易部署和易維護(hù)的分布式系統(tǒng)開發(fā)工具。
微服務(wù)是可以獨(dú)立部署、水平擴(kuò)展、獨(dú)立訪問(或者有獨(dú)立的數(shù)據(jù)庫)的服務(wù)單元,Spring Cloud就是這些微服務(wù)的大管家,采用了微服務(wù)這種架構(gòu)之后,項(xiàng)目的數(shù)量會非常多,Spring Cloud做為大管家就需要提供各種方案來維護(hù)整個生態(tài)。
Spring Cloud就是一套分布式服務(wù)治理的框架,既然它是一套服務(wù)治理的框架,那么它本身不會提供具體功能性的操作,更專注于服務(wù)之間的通訊、熔斷、監(jiān)控等。