YII2集成GOAOP,实现面向方面编程!
引言:
軟件開發(fā)的目標(biāo)是要對(duì)世界的部分元素或者信息流建立模型,實(shí)現(xiàn)軟件系統(tǒng)的工程需要將系統(tǒng)分解成可以創(chuàng)建和管理的模塊。于是出現(xiàn)了以系統(tǒng)模塊化特性的面向?qū)ο蟪绦蛟O(shè)計(jì)技術(shù)。模塊化的面向?qū)ο缶幊虡O度地提高了軟件系統(tǒng)的可讀性、復(fù)用性和可擴(kuò)展性。向?qū)ο蠓椒ǖ慕裹c(diǎn)在于選擇對(duì)象作為模塊的主要單元,并將對(duì)象與系統(tǒng)的所有行為聯(lián)系起來(lái)。對(duì)象成為問(wèn)題領(lǐng)域和計(jì)算過(guò)程的主要元素。但面向?qū)ο蠹夹g(shù)并沒有從本質(zhì)上解決軟件系統(tǒng)的可復(fù)用性。創(chuàng)建軟件系統(tǒng)時(shí),現(xiàn)實(shí)問(wèn)題中存在著許多橫切關(guān)注點(diǎn),比如安全性檢查、日志記錄、性能監(jiān)控,異常處理等,它們的實(shí)現(xiàn)代碼和其他業(yè)務(wù)邏輯代碼混雜在一起,并散落在軟件不同地方(直接把處理這些操作的代碼加入到每個(gè)模塊中),這無(wú)疑破壞了OOP的"單一職責(zé)"原則,模塊的可重用性會(huì)大大降低,這使得軟件系統(tǒng)的可維護(hù)性和復(fù)用性受到極大限制。這時(shí)候傳統(tǒng)的OOP設(shè)計(jì)往往采取的策略是加入相應(yīng)的代理(Proxy)層來(lái)完成系統(tǒng)的功能要求,但這樣的處理明顯使系統(tǒng)整體增加了一個(gè)層次的劃分,復(fù)雜性也隨之增加,從而給人過(guò)于厚重的感覺。由此產(chǎn)生了面向方面編程(AOP)技術(shù)。這種編程模式抽取出散落在軟件系統(tǒng)各處的橫切關(guān)注點(diǎn)代碼,并模塊化,歸整到一起,這樣進(jìn)一步提高軟件的可維護(hù)性、復(fù)用性和可擴(kuò)展性。
AOP簡(jiǎn)介:
AOP: Aspect Oriented Programming 面向切面編程。
面向切面編程(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個(gè)熱點(diǎn)。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。
AOP是OOP的延續(xù),是(Aspect Oriented Programming)的縮寫,意思是面向切面(方面)編程。
主要的功能是:日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等等。
主要的意圖是:將日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來(lái),通過(guò)對(duì)這些行為的分離,我們希望可以將它們獨(dú)立到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進(jìn)而改變這些行為的時(shí)候不影響業(yè)務(wù)邏輯的代碼。
可以通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加功能的一種技術(shù)。AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP可以說(shuō)也是這種目標(biāo)的一種實(shí)現(xiàn)。
假設(shè)把應(yīng)用程序想成一個(gè)立體結(jié)構(gòu)的話,OOP的利刃是縱向切入系統(tǒng),把系統(tǒng)劃分為很多個(gè)模塊(如:用戶模塊,文章模塊等等),而AOP的利刃是橫向切入系統(tǒng),提取各個(gè)模塊可能都要重復(fù)操作的部分(如:權(quán)限檢查,日志記錄等等)。由此可見,AOP是OOP的一個(gè)有效補(bǔ)充。
注意:AOP不是一種技術(shù),實(shí)際上是編程思想。凡是符合AOP思想的技術(shù),都可以看成是AOP的實(shí)現(xiàn)。
AOP 的基本概念:
在面向?qū)ο缶幊讨?#xff0c;類,對(duì)象,封裝,繼承,多態(tài)等概念是描述面向?qū)ο笏枷胫饕g(shù)語(yǔ)。與此類似,在面向方面編程中,同樣存在著一些基本概念:
?????? 聯(lián)結(jié)點(diǎn)(JointPoint) :一個(gè)聯(lián)結(jié)程序執(zhí)行過(guò)程中的一個(gè)特定點(diǎn)。典型的聯(lián)結(jié)點(diǎn)有:調(diào)用一個(gè)方法;方法執(zhí)行這個(gè)過(guò)程本身;類初始化;對(duì)象初始化等。聯(lián)結(jié)點(diǎn)是 AOP 的核心概念之一,它用來(lái)定義在程序的哪里通過(guò) AOP 加入新的邏輯。
??????? 切入點(diǎn)(Pointcut) :一個(gè)切入點(diǎn)是用來(lái)定義某一個(gè)通知該何時(shí)執(zhí)行的一組聯(lián)結(jié)點(diǎn)。通過(guò)定義切入點(diǎn),我們可以精確地控制程序中什么組件接到什么通知。上面我們提到,一個(gè)典型的聯(lián)結(jié)點(diǎn)是方法調(diào)用,而一個(gè)典型的切入點(diǎn)就是對(duì)某一個(gè)類的所在方法調(diào)用的集合。通常我們會(huì)通過(guò)組建復(fù)雜的切入點(diǎn)來(lái)控制通知什么時(shí)候被執(zhí)行。
??????? 通知(Advice) :在某一個(gè)特定的聯(lián)結(jié)點(diǎn)處運(yùn)行的代碼稱為“通知”。通知有很多種,比如
在聯(lián)結(jié)點(diǎn)之前執(zhí)行的前置通知(before advice)和在聯(lián)結(jié)點(diǎn)之后執(zhí)行的后置通知(after advice) 。
?????? 方面(Aspect) :通知和切入點(diǎn)的組合叫做方面,所以,方面定義了一段程序中應(yīng)該包括的邏輯,以及何時(shí)應(yīng)該執(zhí)行該邏輯。
?????? 織入(Weaving) :織入是將方面真正加入程序代碼的過(guò)程。對(duì)于靜態(tài) AOP 方案而言,織入是在編譯時(shí)完成的,通常是在編譯過(guò)程中增加一個(gè)步驟。類似的,動(dòng)態(tài) AOP 方案則是在程序運(yùn)行是動(dòng)態(tài)織入的。
?????? 目標(biāo)(Target) :如果一個(gè)對(duì)象的執(zhí)行過(guò)程受到某一個(gè) AOP 的修改,那么它就叫一個(gè)目標(biāo)對(duì)象。目標(biāo)對(duì)象通常也稱為被通知對(duì)象。
?????? 引入(Introduction) :?? 通過(guò)引入,可以在一個(gè)對(duì)象中加入新的方法或?qū)傩?#xff0c;以改變它的結(jié)構(gòu),這樣即使該對(duì)象的類沒有實(shí)現(xiàn)某一個(gè)接口,也可以修改它,使之成為該接口的一個(gè)實(shí)現(xiàn)。? ?
?????? 靜態(tài)和動(dòng)態(tài):靜態(tài) AOP 和動(dòng)態(tài) AOP 兩者之間的區(qū)別主要在于什么時(shí)間織入,以及如何織入。最早的 AOP 實(shí)現(xiàn)大多都是靜態(tài)的。在靜態(tài) AOP 中,織入是編譯過(guò)程的一個(gè)步驟。用Java 的術(shù)語(yǔ)說(shuō),靜態(tài) AOP 通過(guò)直接對(duì)字節(jié)碼進(jìn)行操作,包括修改代碼和擴(kuò)展類,來(lái)完成織入過(guò)程。顯然,這種辦法生成的程序性能很好,因?yàn)樽詈蟮慕Y(jié)果就是普通的 Java 字節(jié)碼,在運(yùn)行時(shí)不再需要特別的技巧來(lái)確定什么時(shí)候應(yīng)該執(zhí)行通知。這種方法的缺點(diǎn)是,如果想對(duì)方面做什么修改,即使只是加入一個(gè)新的聯(lián)結(jié)點(diǎn),都必須重新編譯整個(gè)程序。AspectJ 是靜態(tài) AOP 的一個(gè)典型例子。與靜態(tài) AOP 不同,動(dòng)態(tài) AOP 中織入是在運(yùn)行時(shí)動(dòng)態(tài)完成的。織入具體是如何完成的,各個(gè)實(shí)現(xiàn)有所不同。Spring AOP 采取的方法是建立代理,然后代理在適當(dāng)?shù)臅r(shí)候執(zhí)行通知。動(dòng)態(tài) AOP 的一個(gè)弱點(diǎn)就在于,其性能一般不如靜態(tài) AOP。而動(dòng)態(tài)AOP 的主要優(yōu)點(diǎn)在于可以隨時(shí)修改程序的所有方面,而不需重新編譯目標(biāo)。
AOP實(shí)踐:
YII2框架本身?yè)碛幸粋€(gè)功能,叫做行為.它可以動(dòng)態(tài)的為當(dāng)前的類附加額外的功能,但這種功能在代碼層級(jí)結(jié)構(gòu)是靜態(tài)的,有侵入性的。
下面以YII2框架集成go!aop庫(kù)為例,介紹在YII2中如何實(shí)現(xiàn)AOP編程.(go!aop簡(jiǎn)介,可以參考go!aop的官網(wǎng).)
由于YII框架擁有自己的類加載器,所在集成go!aop的時(shí)候,不能正常的工作,所以要將其禁用掉,使用composer提供的類加載器。
如下代碼所示(這里使用YII2高級(jí)應(yīng)用模板):
1、找到? spl_autoload_register(['Yii', 'autoload'], true, true);? (PROJECT_PATH/vendor/yiisoft/yii2/Yii.php) 將其禁用掉.
2、執(zhí)行? composer require goaop/framework
3、修改composer.json文件,加入如下代碼段:
4、 在frontend 目錄下創(chuàng)建一個(gè)components是目錄,并新建一個(gè)類AopAspectKernel,例如:
?
5、在forntend目錄下在新建一個(gè)類InitAopComponent,并使其實(shí)現(xiàn)BootstrapInterface,使其可以在YII2框架引導(dǎo)時(shí)被自動(dòng)引導(dǎo)
?
6、在frontend/config/params.php中新增如下代碼:
?
7、在frontend下面新建aspects目錄,并新建類MonitorAspect,代碼如下:
?
9、修改frontend/config/main.php文件,并在components數(shù)組下新增一個(gè)key,代碼如下:
?
10、修改frontend/config/main.php文件,并在bootstrap數(shù)組下新增aop值,代碼如下:
至此,YII2整合go!aop完成...
?
轉(zhuǎn)載于:https://www.cnblogs.com/cmacro/p/9327602.html
總結(jié)
以上是生活随笔為你收集整理的YII2集成GOAOP,实现面向方面编程!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【洛谷P1538】迎春舞会之数字舞蹈
- 下一篇: PHP数组——自定义排序