一些想法
? ? ? ?雖然說(shuō)接觸spring已經(jīng)這么長(zhǎng)時(shí)間了蜂挪,不管大大小小的項(xiàng)目基本都用到了spring献汗,雖然說(shuō)到spring大家都會(huì)想到什么aop和ioc(di) 蟀伸,但是只是知道spring主要是由這兩個(gè)方面組成,但實(shí)際用起來(lái)耳高,也只是一些注解什么的,也沒(méi)有深入的去了解他的機(jī)制是什么蚂子,所以萌庆,最近決定要好好捋一捋spring,因?yàn)殡m然每天都在用沙咏,但是還是覺(jué)得少了點(diǎn)什么辨图,so,廢話不多說(shuō)肢藐,let`s go故河。
一 ioc和aop
1.1 ioc
竟然學(xué)到spring那還是要簡(jiǎn)單了解一下ioc和aop的,首先說(shuō)一下ioc(di)吆豹,即控制反轉(zhuǎn)鱼的,或者是依賴注入,假設(shè)我們有一個(gè)騎士痘煤,和一個(gè)殺boss的任務(wù)
```
/**
* 這是一個(gè)只能殺boss的騎士 實(shí)現(xiàn)了knight的接口
*/
public class KillTheBossKnightimplements Knight{
private KillTheTimokillTheTimo;
? ? public KillTheBossKnight(){
this.killTheTimo =new KillTheTimo();
? ? }
@Override
? ? public void doTheJob() {
System.out.println("殺死了一個(gè)提莫大魔王");
? ? }
public KillTheTimogetKillTheTimo() {
return killTheTimo;
? ? }
public void setKillTheTimo(KillTheTimo killTheTimo) {
this.killTheTimo = killTheTimo;
? ? }
```
可以看到要想讓騎士完成殺死提莫的任務(wù)凑阶,就需要將這個(gè)任務(wù)通過(guò)騎士的構(gòu)造函數(shù)注入,這樣這兩個(gè)類就緊耦合在一起衷快,將這個(gè)具體的任務(wù)和這個(gè)騎士緊緊的耦合在了一起宙橱,那如果這個(gè)其實(shí)要去做其他任務(wù)呢?這還需要修改他的構(gòu)造,這樣的代碼就很不漂亮师郑,因?yàn)轳詈隙仍礁吆哂拢笃诰S護(hù)的成本就越高,所以我們可以通過(guò)另外一種方式來(lái)給來(lái)給騎士下發(fā)任務(wù)呕乎。
接下來(lái)有請(qǐng)我們勇敢的騎士上場(chǎng)
```
/**
* 沒(méi)有將具體的操作交給這個(gè)騎士积担,而只是給了他一個(gè)任務(wù)
*/
public class BraveKnight {
public Jobjob;
? ? public BraveKnight(Job job){
this.job = job;
? ? }
public void doTheJob(){
job.doTheJob();
? ? }
}
```
從這里可以看出,這個(gè)騎士只是在構(gòu)造里面?zhèn)魅肓艘粋€(gè)Job 猬仁,具體是什么Job他并不知道帝璧,所以這就是di的意義所在,這個(gè)騎士只知道他有任務(wù)湿刽,但是具體是什么任務(wù)的烁,只有等他具體接收的時(shí)候才能知道,所以他就可以成為很多騎士诈闺,殺死提莫的騎士渴庆,殺死亞索的騎士。雅镊。襟雷。這就是di所帶來(lái)最大的收益——松耦合。所以我們繼續(xù)向下操作
```
Job killYasuo =new KillTheYasuo();
BraveKnight braveKnight =new BraveKnight(killYasuo);
braveKnight.doTheJob();
```
這樣仁烹,就可以把殺死坑逼亞索的任務(wù)交給了這個(gè)騎士耸弄,這樣這個(gè)其實(shí)就可以為所欲為的做任何他想做的事了,而不是僅僅只殺死一只提莫卓缰。
這就是依賴注入的思想计呈。
1.2 aop
說(shuō)完了ioc 接下里繼續(xù)說(shuō)說(shuō)aop
aop 又稱面向切面編程,相對(duì)于面向?qū)ο缶幊陶骰#@又是一個(gè)更牛逼的思想捌显,那么何為aop呢,工作中一般任務(wù)是怎么劃分的总寒?基本分為兩種扶歪,一種是按照業(yè)務(wù)邏輯分,比如偿乖,訂單系統(tǒng)击罪,購(gòu)物車系統(tǒng)等等,這是在業(yè)務(wù)層面劃分的贪薪,還有一種是從代碼層面媳禁,視圖層啊,業(yè)務(wù)層啊画切,數(shù)據(jù)處理層啊竣稽,這些劃分就是為了更好去處理一些事情,讓工作變得更加有效率,代碼結(jié)構(gòu)更加清晰毫别。aop也可以理解成這樣的一種思想娃弓,一般被定義成一種實(shí)現(xiàn)關(guān)注點(diǎn)分離的技術(shù)。系統(tǒng)是由多個(gè)模塊組成岛宦,每個(gè)模塊負(fù)責(zé)自己的一個(gè)特殊的功能台丛,但是除了自己的任務(wù)以外,往往這些模塊還需要處理其他事情砾肺,比如權(quán)限挽霉,日志,事務(wù)等的管理变汪,這是每個(gè)系統(tǒng)都要面臨的問(wèn)題侠坎,而aop的思想就是將這些跟主業(yè)務(wù)無(wú)關(guān)但是又必須需要的相同的東西剝離出去統(tǒng)一管理,這樣就能讓這些模塊具有更高的內(nèi)聚性裙盾,更加專注于自身的業(yè)務(wù)实胸,從而使代碼更加簡(jiǎn)潔。
接下來(lái)我們繼續(xù)以騎士與坑逼提莫的故事繼續(xù)向下細(xì)談
我們假設(shè)每次在騎士執(zhí)行任務(wù)的時(shí)候都有一個(gè)人來(lái)記錄他的行為番官,在每次執(zhí)行任務(wù)之前和之后都會(huì)記錄庐完,我們就叫他死歌吧。我們來(lái)把他創(chuàng)造出來(lái)
```
public class DeadSinger {
public void singBeforeJob(){
System.out.println("騎士馬上就要干掉那個(gè)家伙了@鹉谩<偻省署咽!");
? ? }
public void singAfterJob(){
System.out.println("騎士干掉了那個(gè)家伙了=辍!宁否!");
? ? }
}
```
在每次騎士執(zhí)行doTheJob的時(shí)候都需要調(diào)用死歌的這兩個(gè)方法窒升,接下來(lái)我們來(lái)繼續(xù)操作
```
public BraveKnight(Job job,DeadSinger deadSinger){
this.job = job;
? ? this.deadSinger = deadSinger;
}
public void doTheJob(){
deadSinger.singBeforeJob();
? ? job.doTheJob();
? ? deadSinger.singAfterJob();
}
```
我們?cè)隍T士都構(gòu)造中傳入了這個(gè)死歌,并在他執(zhí)行Job的前后做出了記錄慕匠,當(dāng)騎士在執(zhí)行任務(wù)的時(shí)候就會(huì)有記錄饱须,但是這里總感覺(jué)有點(diǎn)不對(duì)勁,為嘛這個(gè)騎士需要管理這個(gè)死歌台谊,騎士只需要專心做他的任務(wù)就行了蓉媳,為何還要關(guān)系死歌的活動(dòng)呢,這就很奇怪了锅铅,而且把死歌注入這個(gè)騎士的體力酪呻,呃,想想有點(diǎn)可怕盐须。所以我們就需要將死歌記錄從這個(gè)騎士執(zhí)行任務(wù)中剝離出來(lái)玩荠,讓死歌專心記錄,讓騎士專心做任務(wù),并且騎士不應(yīng)該能感受到死歌的存在阶冈,這就是aop的思想闷尿,具體的實(shí)現(xiàn),我們下回再聊女坑。