- Java EE互聯(lián)網(wǎng)輕量級(jí)框架整合開(kāi)發(fā):SSM+Redis+Spring微服務(wù)(上下冊(cè))
- 楊開(kāi)振 劉家成
- 6868字
- 2021-08-13 19:40:07
第2章
認(rèn)識(shí)SSM框架、Redis和微服務(wù)
本章目標(biāo)
1. 了解Spring IoC和Spring AOP的基礎(chǔ)概念
2. 了解MyBatis的特點(diǎn)
3. 了解Spring MVC的特點(diǎn)
4. 了解為什么要使用NoSQL(Redis)及Redis的優(yōu)點(diǎn)
5. 掌握SSM和Redis的基本結(jié)構(gòu)框圖和各種技術(shù)的作用
2.1 Spring框架
Spring框架是Java中應(yīng)用最廣的框架。它的成功來(lái)自理念,而不是技術(shù)本身,它的理念包括控制反轉(zhuǎn)(Inversion of Control,IoC)和面向切面編程(Aspect Oriented Programming,AOP)。
2.1.1 Spring IoC簡(jiǎn)介
IoC是一個(gè)容器,在Spring中,它認(rèn)為一切Java資源都是Java Bean,容器的目標(biāo)就是管理這些Bean和它們之間的關(guān)系。所以在Spring IoC里面裝載著各種Bean,其實(shí)也可以理解為Java的各種資源。IoC容器管理Java Bean的構(gòu)建、事件、行為等。除此之外,各個(gè)Java Bean之間會(huì)存在一定的依賴(lài)關(guān)系,比如班級(jí)是由老師和學(xué)生組成的,假設(shè)老師、學(xué)生都是Java Bean,那么顯然二者之間形成了依賴(lài)關(guān)系,老師和學(xué)生有教育和被教育的關(guān)系。這些Spring IoC容器都能夠?qū)ζ溥M(jìn)行管理,只是Spring IoC管理對(duì)象和其依賴(lài)關(guān)系不是人為構(gòu)建的,而是由Spring IoC通過(guò)描述構(gòu)建的,也就是說(shuō),Spring是依靠描述來(lái)完成對(duì)象的構(gòu)建及其依賴(lài)關(guān)系的。
比如插座,它依賴(lài)國(guó)家標(biāo)準(zhǔn)(這個(gè)標(biāo)準(zhǔn)可以定義為一個(gè)接口——Socket)定義,現(xiàn)有兩種插座(Socket1和Socket2),如圖1-1所示。

圖2-1 使用插座圖
有兩種插座可供選擇,具體使用哪種呢?我們可以通過(guò)代碼來(lái)實(shí)現(xiàn)使用插座1(Socket1),如代碼清單2-1所示。
代碼清單2-1:使用插座1(Socket1)

使用Socket socket = new Socket1();后,國(guó)家標(biāo)準(zhǔn)插座接口(Socket)就和插座1(Socket1)捆綁在一起了。這樣會(huì)有一個(gè)弊端:如果使用其他插座,就需要修改代碼。在這種情況下,Socket接口和其實(shí)現(xiàn)類(lèi)Socket1耦合了,如果有一天不再使用Socket1,而要使用Socket2,那么就要把代碼修改為如代碼清單2-2所示。
代碼清單2-2:使用插座2(Socket2)

如果有其他更好的插座,那么豈不是還要修改代碼?一個(gè)大型互聯(lián)網(wǎng)的對(duì)象成千上萬(wàn),如果要不斷修改代碼,那么對(duì)系統(tǒng)的可靠性將是極大的挑戰(zhàn),Spring IoC可以解決這個(gè)問(wèn)題。
首先,我們不用new的方式構(gòu)建對(duì)象,而使用配置的方式構(gòu)建對(duì)象,然后讓Spring IoC容器自己通過(guò)配置找到插座。用一段XML描述插座和用戶(hù)的引用插座1,如代碼清單2-3所示。
代碼清單2-3:使用Spring IoC注入插座1給用戶(hù)

請(qǐng)注意這些不是Java代碼,而是XML配置文件,換句話說(shuō)只要把配置切換為

就可以向用戶(hù)信息中注入插座2,顯然,切換插座的實(shí)現(xiàn)類(lèi)十分方便。這個(gè)時(shí)候Socket接口可以不依賴(lài)任何插座,只需要通過(guò)配置就能切換,如圖2-2所示。

圖2-2 Spring的控制反轉(zhuǎn)
圖2-2的配置信息是“我要插座2”,相當(dāng)于XML依賴(lài)關(guān)系配置,這個(gè)時(shí)候Spring IoC只會(huì)拿到插座2,然后通過(guò)國(guó)家標(biāo)準(zhǔn)插座接口提供給使用者。換句話說(shuō),這是一種被動(dòng)的行為,通過(guò)向IoC容器注入描述信息得到資源(Bean),控制權(quán)在Spring IoC容器中,它會(huì)根據(jù)描述找到使用者需要的資源,這就是控制反轉(zhuǎn)的含義。
這樣的好處是Socket接口不再依賴(lài)某個(gè)實(shí)現(xiàn)類(lèi),需要使用某個(gè)實(shí)現(xiàn)類(lèi)時(shí)通過(guò)配置信息就可以完成了。想修改或者加入其他資源可以通過(guò)配置完成,不需要再用new關(guān)鍵字構(gòu)建對(duì)象,依賴(lài)關(guān)系也可以通過(guò)配置完成,即時(shí)地管理它們之間的關(guān)系。
用戶(hù)不需要找資源,只要向Spring IoC容器描述所需資源,Spring IoC就會(huì)自己尋找,這就是Spring IoC的理念。這樣就把Bean之間的依賴(lài)關(guān)系解耦了,更容易寫(xiě)出結(jié)構(gòu)清晰的程序。除此之外,Spring IoC還提供對(duì)Java Bean生命周期的管理,可以延遲加載,可以在其生命周期內(nèi)定義一些行為等,更加方便有效地管理和使用Java資源,這些在未來(lái)都可以學(xué)習(xí)到,這就是Spring IoC的魅力。
2.1.2 Spring AOP
IoC的目標(biāo)是管理Bean,而B(niǎo)ean是Java面向?qū)ο缶幊蹋∣OP)的基礎(chǔ),比如聲明一個(gè)用戶(hù)類(lèi)、插座類(lèi)等都是基于面向?qū)ο蟮母拍睢?/p>
有些情況是面向?qū)ο缶幊虥](méi)辦法處理的。舉個(gè)例子,生產(chǎn)部門(mén)的訂單、生產(chǎn)部門(mén)、財(cái)務(wù)部門(mén)三者符合OOP的設(shè)計(jì)理念。訂單發(fā)出,生產(chǎn)部門(mén)審批通過(guò)準(zhǔn)備付款,但是財(cái)務(wù)部門(mén)發(fā)現(xiàn)訂單的價(jià)格超過(guò)預(yù)算,需要取消訂單。顯然超支限定已經(jīng)不只影響財(cái)務(wù)部門(mén)了,還會(huì)影響生產(chǎn)部門(mén)之前所做的審批,需要把它們做作廢處理。這個(gè)超支影響了訂單、生產(chǎn)部門(mén)和財(cái)務(wù)部門(mén)3個(gè)OOP對(duì)象。在現(xiàn)實(shí)中,這樣的限制的影響跨越了3個(gè)甚至更多的對(duì)象,并且影響了它們之間的協(xié)作。所以只用OOP并不完善,還需要協(xié)調(diào)它們之間的操作,這便是需要面向切面編程的原因,我們可以通過(guò)它去協(xié)調(diào)多個(gè)對(duì)象之間的操作,如圖2-3所示。

圖2-3 Spring面向切面編程的理念
在圖2-3中,實(shí)線是訂單提交的流程,虛線是訂單駁回的流程,影響它們的條件是預(yù)算超額,這是一個(gè)對(duì)多個(gè)對(duì)象產(chǎn)生影響的限制條件。
Spring AOP常用于數(shù)據(jù)庫(kù)事務(wù)的編程,經(jīng)常發(fā)生類(lèi)似的情況,例如,我們?cè)诟峦陻?shù)據(jù)庫(kù)后,不知道下一步是否會(huì)成功,如果下一步失敗,則使用數(shù)據(jù)庫(kù)事務(wù)的回滾功能回滾事務(wù),使第一步的數(shù)據(jù)庫(kù)更新作廢。在Spring AOP實(shí)現(xiàn)的數(shù)據(jù)庫(kù)事務(wù)管理中,是以異常信息作為消息的。在默認(rèn)情況下(可以通過(guò)Spring的配置修改),只要Spring接收到了異常信息,就會(huì)將數(shù)據(jù)庫(kù)的事務(wù)回滾,而不需要通過(guò)代碼實(shí)現(xiàn)這個(gè)過(guò)程,從而保證數(shù)據(jù)的一致性。比如上面的例子,可用一段偽代碼進(jìn)行一些必要的說(shuō)明,如代碼清單2-4所示。
代碼清單2-4:Spring AOP處理訂單

這里完全看不到數(shù)據(jù)庫(kù)連接、事務(wù)獲取和關(guān)閉的代碼,只是在方法上標(biāo)注了注解@Transactional,不需要再編寫(xiě)麻煩的try...catch...finally...語(yǔ)句了。在現(xiàn)實(shí)中,Spring AOP的編程也是如此,關(guān)于數(shù)據(jù)庫(kù)操作的內(nèi)容都被Spring AOP封裝好了,只要遇到注解@Transactional,就不需要自己編寫(xiě)數(shù)據(jù)庫(kù)操作的代碼。這樣使得開(kāi)發(fā)者不再需要關(guān)注功能性的代碼,專(zhuān)注于業(yè)務(wù)代碼就可以了。開(kāi)發(fā)者所需要知道的是只要方法中發(fā)生了異常,Spring就會(huì)回滾事務(wù),而數(shù)據(jù)庫(kù)的開(kāi)閉Spring也會(huì)自動(dòng)完成。當(dāng)然這段話還不算準(zhǔn)確,因?yàn)槭聞?wù)和業(yè)務(wù)是十分復(fù)雜的,還有許多細(xì)節(jié)需要注意,只是在入門(mén)的章節(jié)沒(méi)有必要談得如此復(fù)雜,后面會(huì)詳細(xì)剖析它們。
2.2 MyBatis簡(jiǎn)介
MyBatis的前身是Apache的開(kāi)源項(xiàng)目iBATIS。iBATIS一詞來(lái)源于internet和abatis的組合,是一個(gè)基于Java的持久層框架。2010年,這個(gè)項(xiàng)目由Apache software foundation遷移到Google code,并更名為MyBatis。2013年11月,MyBatis遷移到GitHub上,目前由GitHub維護(hù)。
MyBatis的優(yōu)勢(shì)在于靈活,它幾乎可以代替JDBC,同時(shí)提供了接口編程。目前MyBatis的數(shù)據(jù)訪問(wèn)層DAO(Data Access Objects)是不需要實(shí)現(xiàn)類(lèi)的,它只需要一個(gè)接口和XML(或者注解)。MyBatis提供自動(dòng)映射、動(dòng)態(tài)SQL、級(jí)聯(lián)、緩存、注解、代碼和SQL分離等特性,具有使用方便的特點(diǎn),同時(shí)可以對(duì)SQL進(jìn)行優(yōu)化。因?yàn)槠渚哂蟹庋b少、映射多樣化、支持存儲(chǔ)過(guò)程、可以進(jìn)行SQL優(yōu)化等特點(diǎn),使得它取代Hibernate成為Java互聯(lián)網(wǎng)中首選的持久框架。
Hibernate作為一種曾經(jīng)十分流行的框架,有無(wú)可替代的優(yōu)勢(shì),這里有必要討論一下它和MyBatis的區(qū)別。由于MyBatis和Hibernate都是持久層框架,都涉及數(shù)據(jù)庫(kù),所以首先定義一個(gè)數(shù)據(jù)庫(kù)表——角色表(t_role),其結(jié)構(gòu)如圖2-4所示。

圖2-4 角色表
根據(jù)這個(gè)角色表,我們可以用一個(gè)POJO(Plain Ordinary Java Object)和這張表定義的字段對(duì)應(yīng)起來(lái),如代碼清單2-5所示。
代碼清單2-5:定義角色POJO

無(wú)論是MyBatis還是Hibernate,都是依靠某種方法,將數(shù)據(jù)庫(kù)的表和POJO映射起來(lái),這樣程序員就可以通過(guò)操作POJO來(lái)完成相關(guān)的邏輯了。
2.2.1 Hibernate簡(jiǎn)介
要將POJO和數(shù)據(jù)庫(kù)映射起來(lái)需要給這些框架提供映射規(guī)則,所以下一步要提供映射的規(guī)則,如圖2-5所示。

圖2-5 映射規(guī)則
在MyBatis或者Hibernate中可以通過(guò)XML或者注解的方式提供映射規(guī)則,這里討論XML方式,因?yàn)樵贛yBatis中,注解方式會(huì)受到一定的限制,所以MyBatis通常使用XML方式實(shí)現(xiàn)映射關(guān)系。
我們把POJO對(duì)象和數(shù)據(jù)庫(kù)表相互映射的框架稱(chēng)為對(duì)象關(guān)系映射(Object Relational Mapping,ORM,或O/RM,或O/R mapping)框架。無(wú)論MyBatis還是Hibernate都可以被稱(chēng)為ORM框架,只是Hibernate的設(shè)計(jì)理念是完全面向POJO的,而MyBatis不是。Hibernate基本不再需要編寫(xiě)SQL就可以通過(guò)映射關(guān)系來(lái)操作數(shù)據(jù)庫(kù),是一種全表映射的體現(xiàn);而MyBatis不同,它需要用戶(hù)提供SQL運(yùn)行。
Hibernate是將POJO和數(shù)據(jù)庫(kù)表對(duì)應(yīng)的映射文件,如代碼清單2-6所示。
代碼清單2-6:Hibernate映射文件

先對(duì)POJO和角色表進(jìn)行映射,再對(duì)POJO進(jìn)行操作,從而影響角色表的數(shù)據(jù),比如對(duì)其增、刪、查、改,可以按照如代碼清單2-7所示的方式操作。
代碼清單2-7:Hibernate通過(guò)Session操作數(shù)據(jù)庫(kù)數(shù)據(jù)

這里沒(méi)有看到SQL,那是因?yàn)镠ibernate會(huì)根據(jù)映射關(guān)系來(lái)生成對(duì)應(yīng)的SQL,程序員不用精通SQL,通過(guò)POJO就能夠操作對(duì)應(yīng)數(shù)據(jù)庫(kù)的表了。
這在管理系統(tǒng)時(shí)代是十分有利的。因?yàn)楣芾硐到y(tǒng)優(yōu)先考慮的是業(yè)務(wù)邏輯的實(shí)現(xiàn),然后才是性能,使用Hibernate的建模方式是十分有利于分析業(yè)務(wù)的,所以Hibernate成為那個(gè)時(shí)代的主流持久框架。
2.2.2 MyBatis
應(yīng)該說(shuō),MyBatis框架成為當(dāng)前Java互聯(lián)網(wǎng)持久框架的首選,與Hibernate不同,MyBatis不屏蔽SQL。不屏蔽SQL的優(yōu)勢(shì)在于,程序員可以自己制定SQL規(guī)則,無(wú)須Hibernate自動(dòng)生成規(guī)則,這樣能夠更加精確地定義SQL,從而優(yōu)化性能。它更符合移動(dòng)互聯(lián)網(wǎng)高并發(fā)、大數(shù)據(jù)、高性能、快響應(yīng)的要求。
與Hibernate一樣,MyBatis需要一個(gè)映射文件把POJO和角色表對(duì)應(yīng)起來(lái)。MyBatis映射文件如代碼清單2-8所示。
代碼清單2-8:MyBatis映射文件

這里的resultMap元素用于定義映射規(guī)則,而實(shí)際上當(dāng)MyBatis滿(mǎn)足一定的規(guī)則時(shí),可以自動(dòng)完成映射,增、刪、查、改對(duì)應(yīng)insert、delete、select、update四個(gè)元素,這是十分明顯的。
注意mapper元素中的namespace屬性,它要和一個(gè)接口的全限定名保持一致,里面的SQL的id也需要和接口定義的方法完全保持一致,定義MyBatis映射接口,如代碼清單2-9所示。
代碼清單2-9:定義MyBatis映射接口

這就定義了MyBatis映射接口。到這里或許初學(xué)的讀者會(huì)有一個(gè)很大的疑問(wèn),就是是否需要定義這個(gè)接口的一個(gè)實(shí)現(xiàn)類(lèi)呢?答案是不需要,關(guān)于這點(diǎn)我們?cè)谟懻揗yBatis原理時(shí)會(huì)進(jìn)一步解釋。
下面就可以通過(guò)RoleMapper接口完成角色類(lèi)的增、刪、查、改了,如代碼清單2-10所示。
代碼清單2-10:MyBatis對(duì)角色類(lèi)的增、刪、查、改

顯然,MyBatis在業(yè)務(wù)邏輯上和Hibernate是大同小異的。其區(qū)別在于,MyBatis需要提供接口和SQL,這意味著它的工作量會(huì)比Hibernate大,但是由于自定義SQL、映射關(guān)系,所以其靈活性、可優(yōu)化性超過(guò)了Hibernate。因?yàn)橐粭lSQL的性能可能相差十幾倍到幾十倍,所以互聯(lián)網(wǎng)的可優(yōu)化性、靈活性是十分重要的。
2.2.3 Hibernate和MyBatis的區(qū)別
Hibernate和MyBatis的增、刪、查、改,對(duì)于業(yè)務(wù)邏輯層來(lái)說(shuō)大同小異,對(duì)于映射層,Hibernate的配置不需要接口和SQL,而MyBatis是需要的。Hibernate不需要編寫(xiě)大量的SQL就可以完全映射,同時(shí)提供了日志、緩存、級(jí)聯(lián)(級(jí)聯(lián)比MyBatis強(qiáng)大)等特性,此外,還提供HQL(Hibernate Query Language)對(duì)POJO進(jìn)行操作,使用十分方便,但是它也有致命的缺陷。
由于無(wú)須SQL,當(dāng)關(guān)聯(lián)的表超過(guò)3個(gè)的時(shí)候,通過(guò)Hibernate的級(jí)聯(lián)會(huì)造成很多性能的丟失。例如,訪問(wèn)一個(gè)財(cái)務(wù)報(bào)表,它會(huì)關(guān)聯(lián)財(cái)產(chǎn)信息表,財(cái)產(chǎn)又分為機(jī)械、原料等,顯然機(jī)械和原料的字段是不一樣的,這些關(guān)聯(lián)字段只能根據(jù)特定的條件變化而變化,而Hibernate無(wú)法支持這樣的變化。遇到存儲(chǔ)過(guò)程,Hibernate也只能作罷。更為關(guān)鍵的是性能,在管理系統(tǒng)時(shí)代,對(duì)于性能的要求不是那么苛刻,但是在互聯(lián)網(wǎng)時(shí)代,性能就是系統(tǒng)的根本,響應(yīng)過(guò)慢就會(huì)降低客戶(hù)的忠誠(chéng)度。
以上問(wèn)題通過(guò)MyBatis都可以解決,MyBatis可以自由書(shū)寫(xiě)SQL、支持動(dòng)態(tài)SQL、處理列表、動(dòng)態(tài)生成表名、支持存儲(chǔ)過(guò)程。這樣可以靈活地定義查詢(xún)語(yǔ)句,滿(mǎn)足各類(lèi)需求和性能優(yōu)化的需要,這些在互聯(lián)網(wǎng)系統(tǒng)中是十分重要的。
但MyBatis也有缺陷。首先,它要編寫(xiě)SQL和映射規(guī)則,其工作量稍微大于Hibernate。其次,它支持的工具很有限,不像Hibernate,有許多的插件可以幫助其生成映射代碼和關(guān)聯(lián)關(guān)系,即使使用生成工具,往往也需要開(kāi)發(fā)者進(jìn)行進(jìn)一步簡(jiǎn)化,所以MyBatis采用手工編碼的方式,工作量相對(duì)大些。
對(duì)于性能要求不太苛刻的系統(tǒng),比如管理系統(tǒng)、ERP等推薦使用Hibernate;對(duì)于性能要求高、響應(yīng)快、靈活的互聯(lián)網(wǎng)系統(tǒng)則推薦使用MyBatis。
2.3 Spring MVC簡(jiǎn)介
長(zhǎng)期以來(lái),Struts 2與Spring的結(jié)合一直存在很多問(wèn)題,比如兼容性和類(lèi)臃腫。加之近年來(lái)Struts 2漏洞問(wèn)題頻發(fā),導(dǎo)致使用率大減。與此同時(shí),生于Spring Web項(xiàng)目的MVC(Model View Controller)框架走到了我們面前,Spring MVC結(jié)構(gòu)層次清晰,類(lèi)比較簡(jiǎn)單,并且與Spring的核心IoC和AOP無(wú)縫對(duì)接,成為互聯(lián)網(wǎng)時(shí)代的主流框架。
Spring MVC是一種MVC模式,在MVC模式里,把應(yīng)用程序(輸入邏輯、業(yè)務(wù)邏輯和UI邏輯)分成不同的元素,同時(shí)提供這些元素之間的松耦合,主要涉及三個(gè)概念。
? Model(模型),封裝了應(yīng)用程序的數(shù)據(jù)和由它們組成的POJO。
? View(視圖),負(fù)責(zé)把模型數(shù)據(jù)渲染到視圖上,將數(shù)據(jù)以一定的形式展現(xiàn)給用戶(hù)。
? Controller(控制器),負(fù)責(zé)處理用戶(hù)請(qǐng)求,并建立適當(dāng)?shù)哪P桶阉鼈鬟f給視圖渲染。
在Spring MVC中還可以定義邏輯視圖,通過(guò)其提供的視圖解析器能夠很方便地找到對(duì)應(yīng)的視圖進(jìn)行渲染,或者使用消息轉(zhuǎn)換的功能,比如在Controller的方法內(nèi)加入注解@ResponseBody后,Spring MVC就可以通過(guò)其消息轉(zhuǎn)換系統(tǒng),將數(shù)據(jù)轉(zhuǎn)換為JSON,提供給前端Ajax或者手機(jī)應(yīng)用使用。
Spring MVC的重點(diǎn)是它的流程和一些重要的注解,包括控制器、視圖解析器、視圖等重要內(nèi)容,這些都將在后面進(jìn)行詳細(xì)討論。
2.4 最流行的NoSQL——Redis
Redis是當(dāng)前互聯(lián)網(wǎng)世界最為流行的NoSQL(Not Only SQL)。NoSQL在互聯(lián)網(wǎng)系統(tǒng)中的作用很大,它可以在很大程度上提高互聯(lián)網(wǎng)系統(tǒng)的性能。它具備一些持久層的功能,也可以作為緩存工具。NoSQL數(shù)據(jù)庫(kù)作為持久層,它存儲(chǔ)的數(shù)據(jù)是半結(jié)構(gòu)化的,這就意味著計(jì)算機(jī)在讀入內(nèi)存中只存在少量規(guī)則,因此讀入速度更快。相對(duì)于那些結(jié)構(gòu)化、多范式規(guī)則的關(guān)系數(shù)據(jù)庫(kù)系統(tǒng),它更具性能優(yōu)勢(shì)。作為緩存,它可以支持?jǐn)?shù)據(jù)存入內(nèi)存,只要命中率高,它就能快速響應(yīng),這是因?yàn)閮?nèi)存的讀/寫(xiě)數(shù)據(jù)速度是磁盤(pán)的數(shù)倍到上百倍,其作用如圖2-6所示。

圖2-6 NoSQL的作用
目前對(duì)NoSQL有很多爭(zhēng)議,有些人認(rèn)為它可以取代數(shù)據(jù)庫(kù),而筆者不這么認(rèn)為,因?yàn)閿?shù)據(jù)庫(kù)系統(tǒng)有更好的規(guī)范性和數(shù)據(jù)完整性,功能更強(qiáng)大,作為持久層更為完善,安全性更高。而NoSQL結(jié)構(gòu)松散、不完整,功能有限,目前尚不具備取代數(shù)據(jù)庫(kù)的實(shí)力,但是它的高性能、快響應(yīng)的特性,使它成為一個(gè)很重要的緩存工具。
當(dāng)前Redis成為主要的NoSQL工具,其原因如下。
? 響應(yīng)快速:Redis響應(yīng)非常快,每秒可以執(zhí)行大約110000個(gè)寫(xiě)操作,或者81000個(gè)讀操作,其速度遠(yuǎn)超數(shù)據(jù)庫(kù)。如果存入一些常用的數(shù)據(jù),就能有效提高系統(tǒng)的性能。
? 支持多種數(shù)據(jù)類(lèi)型:包括字符串、哈希結(jié)構(gòu)、列表、集合、可排序集合等。比如字符串可以存入一些Java基礎(chǔ)數(shù)據(jù)類(lèi)型,哈希結(jié)構(gòu)可以存儲(chǔ)對(duì)象,列表可以存儲(chǔ)List對(duì)象等。這使得在應(yīng)用中很容易根據(jù)自己的需要選擇存儲(chǔ)的數(shù)據(jù)類(lèi)型,方便開(kāi)發(fā)。Redis雖然只支持幾種數(shù)據(jù)類(lèi)型,但是它有兩大好處:一是可以滿(mǎn)足存儲(chǔ)各種常用數(shù)據(jù)結(jié)構(gòu)體的需要;二是數(shù)據(jù)類(lèi)型少,規(guī)則就少,需要的判斷和邏輯就少,這樣讀/寫(xiě)的速度就更快。
? 操作都是原子的:所有Redis的操作都是原子的,從而確保當(dāng)兩個(gè)客戶(hù)同時(shí)訪問(wèn)Redis服務(wù)器時(shí),得到的是更新后的值(最新值)。在需要高并發(fā)的場(chǎng)合可以考慮使用Redis的事務(wù)處理一些需要鎖的業(yè)務(wù)。
? MultiUtility工具:Redis 可以在如緩存、消息傳遞隊(duì)列中使用(Redis支持“發(fā)布+訂閱”的消息模式),在Web應(yīng)用中存儲(chǔ)會(huì)話信息(session),或者記錄某個(gè)時(shí)間段頁(yè)面點(diǎn)擊量等需要短暫使用到的數(shù)據(jù)。
Redis具備的這些優(yōu)點(diǎn)使它成為目前主流的NoSQL技術(shù),在Java互聯(lián)網(wǎng)中得到廣泛使用。
2.5 SSM+Redis結(jié)構(gòu)框圖及概述
在Java互聯(lián)網(wǎng)中,將Spring+Spring MVC+MyBatis(SSM)作為主流框架,SSM+Redis的結(jié)構(gòu)框圖,如圖2-7所示。

圖2-7 SSM+Redis結(jié)構(gòu)框圖
結(jié)合圖2-7,下面簡(jiǎn)單介紹圖中各個(gè)組件的功能。
? Spring IoC具有資源(Java Bean)管理、整合、即插即拔的功能。
? Spring AOP具有切面管理,特別是數(shù)據(jù)庫(kù)事務(wù)管理的功能。
? Spring MVC用于把Web開(kāi)發(fā)的模型、視圖和控制器分層,組合成一個(gè)有機(jī)靈活的系統(tǒng)。
? MyBatis提供了一個(gè)數(shù)據(jù)庫(kù)訪問(wèn)的持久層,通過(guò)MyBatis-Spring項(xiàng)目,它能和Spring無(wú)縫對(duì)接。
? Redis作為緩存工具,具有高速度處理數(shù)據(jù)和緩存數(shù)據(jù)的功能,系統(tǒng)在大部分時(shí)間只需要訪問(wèn)緩存,無(wú)須從數(shù)據(jù)庫(kù)磁盤(pán)中重復(fù)讀/寫(xiě);在一些需要高速運(yùn)算的場(chǎng)景下,也可以先用它來(lái)完成運(yùn)算,再把數(shù)據(jù)批量存入數(shù)據(jù)庫(kù),這樣能極大地提升互聯(lián)網(wǎng)系統(tǒng)的性能和響應(yīng)能力。
在未來(lái)我們還會(huì)更為詳細(xì)地討論圖2-7中的各種技術(shù),這也是本書(shū)的核心內(nèi)容。
2.6 Spring微服務(wù)
在當(dāng)今的Java開(kāi)發(fā)領(lǐng)域,人們似乎不提微服務(wù)就不好意思說(shuō)自己是Java程序員,隨著移動(dòng)互聯(lián)網(wǎng)的興起,微服務(wù)成為這幾年Java互聯(lián)網(wǎng)開(kāi)發(fā)的熱點(diǎn)。關(guān)于微服務(wù)的概念,筆者不打算在這里長(zhǎng)篇論述,實(shí)際上微服務(wù)是沒(méi)有明確的規(guī)范的,只需要滿(mǎn)足特定風(fēng)格就可以稱(chēng)為微服務(wù)。筆者喜歡將微服務(wù)架構(gòu)稱(chēng)為一種“帶有一定風(fēng)格的分布式架構(gòu)”,微服務(wù)架構(gòu)有自己的特點(diǎn)和風(fēng)格,但是本質(zhì)上它屬于分布式系統(tǒng)的一種。
當(dāng)前最流行的Java微服務(wù)是Pivotal團(tuán)隊(duì)提供的Spring Cloud,學(xué)習(xí)Spring Cloud需要先學(xué)習(xí)Spring Boot。這里讓我們來(lái)了解一下Spring Boot和Spring Cloud的概念。
Spring Boot的設(shè)計(jì)目的是簡(jiǎn)化新Spring應(yīng)用的初始搭建及開(kāi)發(fā)過(guò)程。該框架使用了特定的方式進(jìn)行配置,使開(kāi)發(fā)人員不再需要定義樣板化的配置。通過(guò)這種方式,Spring Boot致力于在蓬勃發(fā)展的快速應(yīng)用開(kāi)發(fā)領(lǐng)域(rapid application development)成為領(lǐng)導(dǎo)者。簡(jiǎn)單地說(shuō),Spring Boot的設(shè)計(jì)理念是約定優(yōu)于配置,在Spring Boot中會(huì)提供很多默認(rèn)的配置,用戶(hù)可以通過(guò)Spring Boot給予的配置項(xiàng)修改這些配置。大家知道在普通開(kāi)發(fā)中,用戶(hù)需要提供大量的配置和代碼去連接數(shù)據(jù)庫(kù)和其他資源,而在Spring Boot中就不再需要了,它會(huì)提供對(duì)應(yīng)的配置項(xiàng),用戶(hù)只需要跟著這些配置項(xiàng)配置數(shù)據(jù)庫(kù)的連接和屬性就可以了,例如,只需要配置數(shù)據(jù)庫(kù)連接和連接池的屬性就可以使用了,而無(wú)須再編寫(xiě)任何代碼,比如下面的配置。

通過(guò)這樣的配置,就完成了構(gòu)建數(shù)據(jù)庫(kù)連接池的任務(wù),這些是Spring Boot根據(jù)用戶(hù)的配置自動(dòng)完成的,并不需要用戶(hù)編寫(xiě)代碼,它的作用是盡可能減少用戶(hù)編寫(xiě)代碼的工作,使得開(kāi)發(fā)者能夠更快速地開(kāi)發(fā)業(yè)務(wù)。
Spring Cloud是微服務(wù)開(kāi)發(fā)的利器。在微服務(wù)中,一個(gè)龐大的單體系統(tǒng)會(huì)按照業(yè)務(wù)微服務(wù)被拆分為多個(gè)服務(wù),每一個(gè)服務(wù)都是一個(gè)獨(dú)立的產(chǎn)品,可以擁有獨(dú)立的數(shù)據(jù)庫(kù)、服務(wù)器和其他資源,可以獨(dú)立運(yùn)行。比如一個(gè)龐大的電商單體系統(tǒng)可以拆分為用戶(hù)、產(chǎn)品、資金、商戶(hù)等服務(wù),需要通過(guò)各種組件來(lái)管理這些獨(dú)立的服務(wù),并且將它們聯(lián)系起來(lái)。為此,Spring Cloud提供了服務(wù)發(fā)現(xiàn)、服務(wù)注冊(cè)、配置中心、消息總線、負(fù)載均衡、服務(wù)調(diào)用、斷路器、數(shù)據(jù)監(jiān)控等組件。但是請(qǐng)注意,Spring Cloud的這些組件并非都是自己開(kāi)發(fā)的,而是會(huì)選用當(dāng)前開(kāi)源、口碑較好和經(jīng)得起實(shí)踐考驗(yàn)的分布式組件,Spring Cloud會(huì)采用Spring Boot風(fēng)格將這些組件進(jìn)行封裝,所以學(xué)習(xí)Spring Cloud的基礎(chǔ)是Spring Boot。
- HornetQ Messaging Developer’s Guide
- Practical Data Analysis Cookbook
- Java多線程編程實(shí)戰(zhàn)指南:設(shè)計(jì)模式篇(第2版)
- AngularJS Testing Cookbook
- 匯編語(yǔ)言程序設(shè)計(jì)(第2版)
- STM32F0實(shí)戰(zhàn):基于HAL庫(kù)開(kāi)發(fā)
- The DevOps 2.4 Toolkit
- 單片機(jī)應(yīng)用與調(diào)試項(xiàng)目教程(C語(yǔ)言版)
- Extreme C
- 微信小程序開(kāi)發(fā)實(shí)戰(zhàn):設(shè)計(jì)·運(yùn)營(yíng)·變現(xiàn)(圖解案例版)
- Mastering Elixir
- Learning iOS Security
- Python Social Media Analytics
- Serverless工程實(shí)踐:從入門(mén)到進(jìn)階
- Java EE互聯(lián)網(wǎng)輕量級(jí)框架整合開(kāi)發(fā):SSM+Redis+Spring微服務(wù)(上下冊(cè))