前言
作為從事java開(kāi)發(fā)的碼農(nóng),Spring的重要性不言而喻,你可能每天都在和Spring框架打交道。Spring恰如其名的,給java應(yīng)用程序的開(kāi)發(fā)帶了春天般的舒爽感覺(jué)。Spring,可以說(shuō)是任何一個(gè)java開(kāi)發(fā)者通往技術(shù)高階的必備基礎(chǔ)。當(dāng)然,要學(xué)好Spring,尤其是了解Spring的底層原理并不容易,需要花費(fèi)很多時(shí)間和精力來(lái)潛心的研習(xí),并在實(shí)際的項(xiàng)目中不斷的試錯(cuò)和總結(jié),才能形成屬于自己的思維理解。博主對(duì)Spring最初的認(rèn)識(shí)頗淺,項(xiàng)目中遇到問(wèn)題依靠度娘大概也能籠而統(tǒng)之的解決。不過(guò)呢,接觸Spring這么一年多時(shí)間里,對(duì)其框架體系認(rèn)知比較雜亂,深層技術(shù)依然是霧里看花一般,沒(méi)有形成自己的認(rèn)知和理解,這對(duì)編程技術(shù)的提升是十分不利的。鑒于此,才決定靜下心來(lái)從頭至尾系統(tǒng)的學(xué)習(xí)Spring框架,并通過(guò)博客的形式記錄學(xué)習(xí)點(diǎn)滴,分享技術(shù)知識(shí),算是拋磚引玉吧。好了,閑言少敘,咱們開(kāi)始切入正題——
Spring框架核心介紹
DI(Dependency Injection),依賴(lài)注入,和我們常聽(tīng)說(shuō)的另一個(gè)概念 IOC(控制反轉(zhuǎn))其實(shí)歸根結(jié)底實(shí)現(xiàn)的功能是相同的,只是同樣的功能站在不同的角度來(lái)闡述罷了。這里博主就不去過(guò)多的辨析,度娘上有一大堆解釋。我們需要知道的是,什么叫依賴(lài)注入,為什么要依賴(lài)注入。搞清這兩點(diǎn),我想對(duì)Spring的學(xué)習(xí)在思想上就算是上道了。
在沒(méi)用使用Spring的時(shí)候——也就是沒(méi)有依賴(lài)注入的時(shí)候,java應(yīng)用程序的類(lèi)與類(lèi)之間要實(shí)現(xiàn)相互的功能協(xié)作是比較費(fèi)勁的,某個(gè)類(lèi)(A)要實(shí)現(xiàn)它的功能如果需要依賴(lài)另一個(gè)類(lèi)(B)的協(xié)作的話,就需要在A類(lèi)中主動(dòng)創(chuàng)建出B類(lèi)的對(duì)象,才能使用B類(lèi)的方法完成功能(這里看官就不要去糾結(jié)靜態(tài)方法之類(lèi)的情況了)。這等于是A類(lèi)需要負(fù)責(zé)B類(lèi)對(duì)象整個(gè)生命周期的管理。在極度簡(jiǎn)單的情況下,在一個(gè)類(lèi)中new出另一個(gè)類(lèi)的對(duì)象似乎并沒(méi)有什么問(wèn)題,但是復(fù)雜的應(yīng)用程序類(lèi)與類(lèi)的協(xié)作關(guān)系往往是多邊的,我們并不知道一個(gè)類(lèi)功能的實(shí)現(xiàn)會(huì)依賴(lài)多少個(gè)另類(lèi)對(duì)象來(lái)協(xié)作,所以在類(lèi)中自行創(chuàng)建對(duì)象并且管理對(duì)象的整個(gè)生命周期,會(huì)造成代碼的高度耦合以及不可想象的復(fù)雜度。那么,試想,如果我們能將對(duì)象的生命周期交給第三方組件來(lái)管理,當(dāng)某個(gè)類(lèi)需要另外的對(duì)象時(shí)第三方組件就直接創(chuàng)建出來(lái)交給它,這樣,類(lèi)就可以只專(zhuān)注于自己功能的實(shí)現(xiàn),而不用去管理其他類(lèi)對(duì)象的生命周期,這樣類(lèi)的功能就單純了很多。是的,你一定已經(jīng)明白了,Spring(容器)就是這個(gè)第三方組件。我們只需要告訴Spring(容器)有哪些對(duì)象需要管理就行了,不用去關(guān)心Spring框架是如何創(chuàng)建對(duì)象的。這樣,當(dāng)某個(gè)類(lèi)A需要類(lèi)B對(duì)象時(shí),如果類(lèi)B已經(jīng)聲明交給了Sping容器管理,那么在程序運(yùn)行到類(lèi)A需要類(lèi)B時(shí),Spring容器就通過(guò)依賴(lài)注入的方式,將類(lèi)B對(duì)象注入到類(lèi)A中協(xié)助完成業(yè)務(wù)功能。通過(guò)第三方組件的依賴(lài)注入,對(duì)象無(wú)需再自行的創(chuàng)建和管理類(lèi)與類(lèi)之間的依賴(lài)關(guān)系了。對(duì)象的創(chuàng)建依賴(lài)注入的方式也有多種,譬如接口注入,構(gòu)造方法注入,setter方法注入等等。說(shuō)到這里,你對(duì)依賴(lài)注入應(yīng)該有比較直白的認(rèn)知了。至于為什么要依賴(lài)注入,上文已經(jīng)說(shuō)得很明白了,就是為了減少代碼中組件之間的耦合度,我們還是先通過(guò)簡(jiǎn)單示例來(lái)直觀感受下依賴(lài)注入比自己管理對(duì)象的好處吧——
1
2
3
4
5
6
7
8
9
10
11
12
|
public class Man implements Human { private QQCar car; public Man() { this .car = new QQCar(); } @Override public void xiabibi() { } public void driveCar(){ car.drive(); } } |
接口Car暫有兩個(gè)實(shí)現(xiàn):奔馳車(chē)和QQ車(chē),在以上Man類(lèi)和QQCar類(lèi)高度耦合的代碼中,老司機(jī)通過(guò)構(gòu)造器只創(chuàng)建了QQ車(chē)對(duì)象,所以只能開(kāi)QQ車(chē),那么老司機(jī)想開(kāi)奔馳怎么辦呢,你讓他重新創(chuàng)建奔馳車(chē)的對(duì)象嗎?這樣高度耦合的代碼似乎是毫無(wú)辦法的,那么,我們通過(guò)注入對(duì)象的方式對(duì)上述代碼做一番改進(jìn):
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class Man implements Human { private Car car; public Man(Car car) { this .car = car; } @Override public void xiabibi() { } public void driveCar() { car.drive(); } } |
以上代碼根據(jù)多態(tài)特性,通過(guò)構(gòu)造器接口注入的方式屏蔽掉了具體的對(duì)象實(shí)現(xiàn),這樣,老司機(jī)就能想開(kāi)什么車(chē)就開(kāi)什么車(chē)了。這就是依賴(lài)注入帶來(lái)的好處。
AOP(Aspect Oriented Programming),面向切面編程。日常開(kāi)發(fā)中,我們?cè)谕瓿赡硞€(gè)業(yè)務(wù)功能的時(shí)候,寫(xiě)了一堆代碼,到最后代碼優(yōu)化的時(shí)候發(fā)現(xiàn),真正完成業(yè)務(wù)的代碼可能就那么兩句,而其余都是與該部分業(yè)務(wù)相關(guān)度不大,僅僅是為了實(shí)現(xiàn)某種技術(shù)的代碼,是完全可以抽離出去的,于是很自然的,我們會(huì)將其抽取成一個(gè)工具類(lèi),這樣凡是用到的地方只需調(diào)用一下工具方法就ok了。我們?cè)僬靖咭稽c(diǎn)看,各個(gè)業(yè)務(wù)模塊的功能組件中除了完成相關(guān)的業(yè)務(wù)功能外,都有涉及日志、事務(wù)、安全控制等額外的操作等。這些并不是模塊的核心功能,卻又不可或缺。如果將這些額外功能添加進(jìn)代碼,業(yè)務(wù)系統(tǒng)每個(gè)組件都來(lái)一套又顯得太過(guò)重復(fù),而且讓業(yè)務(wù)代碼顯得混亂,不夠純粹。這個(gè)時(shí)候,你問(wèn)上帝,可不可以讓你的業(yè)務(wù)代碼只專(zhuān)注于業(yè)務(wù)的實(shí)現(xiàn),不去管什么日志、事務(wù)等不相干的東西?喔,上帝說(shuō)沒(méi)問(wèn)題,于是就有了AOP。如果說(shuō)依賴(lài)注入的目的是讓相互協(xié)作的組件保持一種較為松散的耦合狀態(tài)的話,AOP則是將遍布應(yīng)用各處的功能分離出來(lái)形成可重用的組件。通俗點(diǎn)說(shuō),日志、事務(wù)等都是可以重用的組件,我們完全可以將分散于業(yè)務(wù)代碼各處的日志、事務(wù)、安全等功能代碼抽離出成為一個(gè)單獨(dú)的工具組件,在Spring的配置中將其進(jìn)行聲明為一個(gè)功能切面,再告訴Spring你想在哪些地方、什么時(shí)機(jī)使用(切入)這些可重用組件就行了。這就是我對(duì)面向切面的簡(jiǎn)單釋義。該篇只是引子,所以博主就只是簡(jiǎn)單闡述一下概念,不做具體的代碼、配置實(shí)現(xiàn),在會(huì)在后續(xù)的博文中將陸續(xù)奉上,歡迎拍磚。
原文鏈接:https://www.cnblogs.com/chenbenbuyi/p/7470834.html