国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

YII2實現(xiàn)面向方面編程

2020-03-22 19:26:20
字體:
供稿:網(wǎng)友
這篇文章給大家介紹的內(nèi)容是YII2實現(xiàn)面向方面編程,有需要的朋友可以參考一下

引言:
軟件開發(fā)的目標是要對世界的部分元素或者信息流建立模型,實現(xiàn)軟件系統(tǒng)的工程需要將系統(tǒng)分解成可以創(chuàng)建和管理的模塊。于是出現(xiàn)了以系統(tǒng)模塊化特性的html' target='_blank'>面向?qū)ο?/u>程序設(shè)計技術(shù)。模塊化的面向?qū)ο缶幊虡O度地提高了軟件系統(tǒng)的可讀性、復(fù)用性和可擴展性。向?qū)ο蠓椒ǖ慕裹c在于選擇對象作為模塊的主要單元,并將對象與系統(tǒng)的所有行為聯(lián)系起來。對象成為問題領(lǐng)域和計算過程的主要元素。但面向?qū)ο蠹夹g(shù)并沒有從本質(zhì)上解決軟件系統(tǒng)的可復(fù)用性。創(chuàng)建軟件系統(tǒng)時,現(xiàn)實問題中存在著許多橫切關(guān)注點,比如安全性檢查、日志記錄、性能監(jiān)控,異常處理等,它們的實現(xiàn)代碼和其他業(yè)務(wù)邏輯代碼混雜在一起,并散落在軟件不同地方(直接把處理這些操作的代碼加入到每個模塊中),這無疑破壞了OOP的 單一職責 原則,模塊的可重用性會大大降低,這使得軟件系統(tǒng)的可維護性和復(fù)用性受到極大限制。這時候傳統(tǒng)的OOP設(shè)計往往采取的策略是加入相應(yīng)的代理(Proxy)層來完成系統(tǒng)的功能要求,但這樣的處理明顯使系統(tǒng)整體增加了一個層次的劃分,復(fù)雜性也隨之增加,從而給人過于厚重的感覺。由此產(chǎn)生了面向方面編程(AOP)技術(shù)。這種編程模式抽取出散落在軟件系統(tǒng)各處的橫切關(guān)注點代碼,并模塊化,歸整到一起,這樣進一步提高軟件的可維護性、復(fù)用性和可擴展性。

AOP簡介:
AOP: Aspect Oriented Programming 面向切面編程。
面向切面編程(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個熱點。利用AOP可以對業(yè)務(wù)邏輯的各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。
AOP是OOP的延續(xù),是(Aspect Oriented Programming)的縮寫,意思是面向切面(方面)編程。
主要的功能是:日志記錄,性能統(tǒng)計,安全控制,事務(wù)處理,異常處理等等。
主要的意圖是:將日志記錄,性能統(tǒng)計,安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進而改變這些行為的時候不影響業(yè)務(wù)邏輯的代碼。
可以通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一添加功能的一種技術(shù)。AOP實際是GoF設(shè)計模式的延續(xù),設(shè)計模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP可以說也是這種目標的一種實現(xiàn)。
假設(shè)把應(yīng)用程序想成一個立體結(jié)構(gòu)的話,OOP的利刃是縱向切入系統(tǒng),把系統(tǒng)劃分為很多個模塊(如:用戶模塊,文章模塊等等),而AOP的利刃是橫向切入系統(tǒng),提取各個模塊可能都要重復(fù)操作的部分(如:權(quán)限檢查,日志記錄等等)。由此可見,AOP是OOP的一個有效補充。
注意:AOP不是一種技術(shù),實際上是編程思想。凡是符合AOP思想的技術(shù),都可以看成是AOP的實現(xiàn)。

AOP 的基本概念:
在面向?qū)ο缶幊讨校悾瑢ο?,封裝,繼承,多態(tài)等概念是描述面向?qū)ο笏枷胫饕g(shù)語。與此類似,在面向方面編程中,同樣存在著一些基本概念:
聯(lián)結(jié)點(JointPoint) :一個聯(lián)結(jié)程序執(zhí)行過程中的一個特定點。典型的聯(lián)結(jié)點有:調(diào)用一個方法;方法執(zhí)行這個過程本身;類初始化;對象初始化等。聯(lián)結(jié)點是 AOP 的核心概念之一,它用來定義在程序的哪里通過 AOP 加入新的邏輯。
切入點(Pointcut) :一個切入點是用來定義某一個通知該何時執(zhí)行的一組聯(lián)結(jié)點。通過定義切入點,我們可以精確地控制程序中什么組件接到什么通知。上面我們提到,一個典型的聯(lián)結(jié)點是方法調(diào)用,而一個典型的切入點就是對某一個類的所在方法調(diào)用的集合。通常我們會通過組建復(fù)雜的切入點來控制通知什么時候被執(zhí)行。
通知(Advice) :在某一個特定的聯(lián)結(jié)點處運行的代碼稱為“通知”。通知有很多種,比如
在聯(lián)結(jié)點之前執(zhí)行的前置通知(before advice)和在聯(lián)結(jié)點之后執(zhí)行的后置通知(after advice) 。
方面(Aspect) :通知和切入點的組合叫做方面,所以,方面定義了一段程序中應(yīng)該包括的邏輯,以及何時應(yīng)該執(zhí)行該邏輯。
織入(Weaving) :織入是將方面真正加入程序代碼的過程。對于靜態(tài) AOP 方案而言,織入是在編譯時完成的,通常是在編譯過程中增加一個步驟。類似的,動態(tài) AOP 方案則是在程序運行是動態(tài)織入的。
目標(Target) :如果一個對象的執(zhí)行過程受到某一個 AOP 的修改,那么它就叫一個目標對象。目標對象通常也稱為被通知對象。
引入(Introduction) : 通過引入,可以在一個對象中加入新的方法或?qū)傩?,以改變它的結(jié)構(gòu),這樣即使該對象的類沒有實現(xiàn)某一個接口,也可以修改它,使之成為該接口的一個實現(xiàn)。

靜態(tài)和動態(tài):靜態(tài) AOP 和動態(tài) AOP 兩者之間的區(qū)別主要在于什么時間織入,以及如何織入。最早的 AOP 實現(xiàn)大多都是靜態(tài)的。在靜態(tài) AOP 中,織入是編譯過程的一個步驟。用Java 的術(shù)語說,靜態(tài) AOP 通過直接對字節(jié)碼進行操作,包括修改代碼和擴展類,來完成織入過程。顯然,這種辦法生成的程序性能很好,因為最后的結(jié)果就是普通的 Java 字節(jié)碼,在運行時不再需要特別的技巧來確定什么時候應(yīng)該執(zhí)行通知。這種方法的缺點是,如果想對方面做什么修改,即使只是加入一個新的聯(lián)結(jié)點,都必須重新編譯整個程序。AspectJ 是靜態(tài) AOP 的一個典型例子。與靜態(tài) AOP 不同,動態(tài) AOP 中織入是在運行時動態(tài)完成的。織入具體是如何完成的,各個實現(xiàn)有所不同。Spring AOP 采取的方法是建立代理,然后代理在適當?shù)臅r候執(zhí)行通知。動態(tài) AOP 的一個弱點就在于,其性能一般不如靜態(tài) AOP。而動態(tài)AOP 的主要優(yōu)點在于可以隨時修改程序的所有方面,而不需重新編譯目標。

AOP實踐:

YII2框架本身擁有一個功能,叫做行為.它可以動態(tài)的為當前的類附加額外的功能,但這種功能在代碼層級結(jié)構(gòu)是靜態(tài)的,有侵入性的。

下面以YII2框架集成go!aop庫為例,介紹在YII2中如何實現(xiàn)AOP編程.(go!aop簡介,可以參考go!aop的網(wǎng)址.)

由于YII框架擁有自己的類加載器,所在集成go!aop的時候,不能正常的工作,所以要將其禁用掉,使用composer提供的類加載器。

如下代碼所示(這里使用YII2高級應(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文件,加入如下代碼段:

 autoload : { psr-4 : { backend// : backend// , frontend// : frontend// , common// : common//  }

4、 在frontend 目錄下創(chuàng)建一個components是目錄,并新建一個類AopAspectKernel,例如:

namespace frontend/components;use frontend/aspects/MonitorAspect;use Go/Core/AspectContainer;use Go/Core/AspectKernel;class AopAspectKernel extends AspectKernel protected function configureAop(AspectContainer $container) $container- registerAspect(new MonitorAspect());}

5、在forntend目錄下在新建一個類InitAopComponent,并使其實現(xiàn)BootstrapInterface,使其可以在YII2框架引導(dǎo)時被自動引導(dǎo)

namespace frontend/components;use yii/base/BootstrapInterface;class InitAopComponent implements BootstrapInterface public function bootstrap($app) print_r(/Yii::$app- params[ aop  $applicationAspectKernel = AopAspectKernel::getInstance(); $applicationAspectKernel- init(/Yii::$app- params[ aop }

6、在frontend/config/params.php中新增如下代碼:

 aop = [ debug = true, appDir = dirname(__DIR__), cacheDir = dirname(__DIR__) . /runtime/aop , includePaths = [ dirname(__DIR__) ]

7、在frontend下面新建aspects目錄,并新建類MonitorAspect,代碼如下:

namespace frontend/aspects;use Go/Aop/Aspect;use Go/Aop/Intercept/MethodInvocation;use Go/Lang/Annotation/Before;class MonitorAspect implements Aspect * Method that will be called before real method * @param MethodInvocation $invocation Invocation * @Before( execution(public frontend/components/AopTestComponent- *(*)) ) public function beforeMethodExecution(MethodInvocation $invocation) $obj = $invocation- getThis(); echo Calling Before Interceptor for method: , is_object($obj) ? get_class($obj) : $obj, $invocation- getMethod()- isStatic() ? :: : - , $invocation- getMethod()- getName(), () , with arguments: , json_encode($invocation- getArguments()), br /n }

9、修改frontend/config/main.php文件,并在components數(shù)組下新增一個key,代碼如下:

 components = [ aop = [ class = frontend/components/InitAopComponent  ]


10、修改frontend/config/main.php文件,并在bootstrap數(shù)組下新增aop值,代碼如下:

 bootstrap = [ log , aop ]

至此,YII2整合go!aop完成...

相關(guān)推薦:

關(guān)于IIS下PHP快三平臺源碼的架設(shè)環(huán)境的配置過程

如何在yii2框架的di容器源碼中了解反射的作用

以上就是YII2實現(xiàn)面向方面編程的詳細內(nèi)容,PHP教程

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 濮阳县| 贡觉县| 瑞丽市| 中山市| 岳西县| 衡南县| 苏尼特左旗| 襄城县| 新安县| 安宁市| 保定市| 南城县| 百色市| 潜江市| 长垣县| 吉木萨尔县| 个旧市| 襄樊市| 朝阳市| 炉霍县| 青阳县| 台山市| 盐山县| 福贡县| 深州市| 星子县| 宁南县| 中宁县| 大连市| 江源县| 通州区| 西畴县| 历史| 皋兰县| 庆阳市| 松阳县| 沙田区| 高雄县| 高雄县| 奇台县| 凤城市|