ホームページ  >  記事  >  バックエンド開発  >  YII2 はアスペクト指向プログラミングを実装します

YII2 はアスペクト指向プログラミングを実装します

不言
不言オリジナル
2018-07-18 16:49:402665ブラウズ

この記事では、YII2 でのアスペクト指向プログラミングの実装について紹介します。必要な友人は参照してください。

はじめに:
ソフトウェア開発の目標は、世界の要素や情報の流れのモデルを確立することです。ソフトウェア システムのエンジニアリングを実現するには、システムを作成可能なコンポーネントと管理モジュールに分解するために必要です。その結果、システムのモジュール性を備えたオブジェクト指向プログラミング技術が登場しました。モジュール式のオブジェクト指向プログラミングにより、ソフトウェア システムの可読性、再利用性、拡張性が大幅に向上します。オブジェクト指向アプローチの焦点は、モジュールの主要ユニットとしてオブジェクトを選択し、そのオブジェクトをシステムのすべての動作に接続することです。オブジェクトは、問題領域と計算プロセスの主要な要素になります。ただし、オブジェクト指向テクノロジーは、ソフトウェア システムの再利用性を本質的に解決するものではありません。ソフトウェア システムを作成する場合、セキュリティ チェック、ロギング、パフォーマンス監視、例外処理など、実際の問題には横断的な懸念事項が数多くあります。それらの実装コードは他のビジネス ロジック コードと混合され、システムのさまざまな部分に分散されます。 (これらの操作を処理するコードを各モジュールに直接追加する)、これは間違いなく OOP の「単一責任」原則を破壊し、モジュールの再利用性が大幅に低下するため、ソフトウェア システムの保守性と再利用性が低下します。非常に制限的です。現時点で、従来の OOP 設計でよく採用される戦略は、対応するプロキシ層を追加してシステムの機能要件を完成させることですが、このような処理は明らかにシステム全体にレベルの分割を追加し、複雑さも増加します。重すぎる感じを与えます。これにより、アスペクト指向プログラミング (AOP) テクノロジが誕生しました。このプログラミング モデルは、ソフトウェア システム全体に散在する横断的な関心コードを抽出し、モジュール化してグループ化することで、ソフトウェアの保守性、再利用性、拡張性をさらに向上させます。

AOP の紹介:
AOP: アスペクト指向プログラミング。
アスペクト指向プログラミング (アスペクト指向とも呼ばれます): アスペクト指向プログラミング (AOP) は、現在のソフトウェア開発においてホットスポットです。 AOP を使用すると、ビジネス ロジックのさまざまな部分を分離できるため、ビジネス ロジックのさまざまな部分間の結合が軽減され、プログラムの再利用性が向上し、開発の効率が向上します。
AOP は OOP の後継であり、(Aspect Oriented Programming) の略称で、アスペクト指向プログラミングを意味します。
主な機能は、ロギング、パフォーマンス統計、セキュリティ制御、トランザクション処理、例外処理などです。
主な目的は、ロギング、パフォーマンス統計、セキュリティ制御、トランザクション処理、例外処理、およびその他のコードをビジネス ロジック コードから分離することです。これらの動作を分離することで、それらを非指導的なビジネスに分離したいと考えています。ロジック メソッド、ビジネス ロジック コードに影響を与えることなく、これらの動作を変更します。
プリコンパイルとランタイムダイナミックプロキシにより、ソースコードを変更することなくプログラムに動的かつ均一に機能を追加できる技術。 AOP は実際には GoF デザイン パターンの継続であり、呼び出し元と呼び出し先のデカップリングを絶えず追求したデザイン パターンであり、AOP はそれを実現したものであると言えます。
アプリケーションを 3 次元構造として考えると、OOP の鋭い点は、システムを垂直に切り込み、システムを多くのモジュール (ユーザー モジュール、記事モジュールなど) に分割することです。 AOP の鋭いエッジは、システムを水平方向に切り込み、各モジュールで繰り返しの操作が必要になる可能性のある部分を抽出することです (権限チェック、ロギングなど)。 AOP が OOP を効果的に補うものであることがわかります。
注: AOP はテクノロジーではなく、実際にはプログラミングのアイデアです。 AOP の考え方に準拠するテクノロジーはすべて、AOP の実装とみなすことができます。

AOP の基本概念:
オブジェクト指向プログラミングでは、クラス、オブジェクト、カプセル化、継承、ポリモーフィズムおよびその他の概念これは、オブジェクト指向の思考を説明する主な用語です。同様に、アスペクト指向プログラミングにも、いくつかの基本概念があります。
JointPoint: 共同プログラムの実行における特定のポイント。一般的な接続ポイントには、メソッドの呼び出し、プロセス自体を実行するメソッド、クラスの初期化、オブジェクトの初期化などが含まれます。接続ポイントは AOP の中核概念の 1 つであり、AOP を通じてプログラム内のどこに新しいロジックを追加するかを定義するために使用されます。
ポイントカット: ポイントカットは、通知を実行するタイミングを定義するために使用される接続ポイントのセットです。ポイントカットを定義することで、プログラム内のどのコンポーネントがどの通知を受け取るかを正確に制御できます。典型的な接続ポイントはメソッド呼び出しであり、典型的なエントリ ポイントは特定のクラスへのメソッド呼び出しのコレクションであると上で述べました。通常、複雑なエントリ ポイントを形成することで、通知がいつ実行されるかを制御します。 ### アドバイスアドバイスには、接続点の前に実行される
preadvice (アドバイス前) や、接続点の後に実行される postadvice (アドバイス後) など、さまざまな種類があります。
       方面(Aspect) :通知和切入点的组合叫做方面,所以,方面定义了一段程序中应该包括的逻辑,以及何时应该执行该逻辑。
       织入(Weaving) :织入是将方面真正加入程序代码的过程。对于静态 AOP 方案而言,织入是在编译时完成的,通常是在编译过程中增加一个步骤。类似的,动态 AOP 方案则是在程序运行是动态织入的。
       目标(Target) :如果一个对象的执行过程受到某一个 AOP 的修改,那么它就叫一个目标对象。目标对象通常也称为被通知对象。
       引入(Introduction) :   通过引入,可以在一个对象中加入新的方法或属性,以改变它的结构,这样即使该对象的类没有实现某一个接口,也可以修改它,使之成为该接口的一个实现。   

       静态和动态:静态 AOP 和动态 AOP 两者之间的区别主要在于什么时间织入,以及如何织入。最早的 AOP 实现大多都是静态的。在静态 AOP 中,织入是编译过程的一个步骤。用Java 的术语说,静态 AOP 通过直接对字节码进行操作,包括修改代码和扩展类,来完成织入过程。显然,这种办法生成的程序性能很好,因为最后的结果就是普通的 Java 字节码,在运行时不再需要特别的技巧来确定什么时候应该执行通知。这种方法的缺点是,如果想对方面做什么修改,即使只是加入一个新的联结点,都必须重新编译整个程序。AspectJ 是静态 AOP 的一个典型例子。与静态 AOP 不同,动态 AOP 中织入是在运行时动态完成的。织入具体是如何完成的,各个实现有所不同。Spring AOP 采取的方法是建立代理,然后代理在适当的时候执行通知。动态 AOP 的一个弱点就在于,其性能一般不如静态 AOP。而动态AOP 的主要优点在于可以随时修改程序的所有方面,而不需重新编译目标。

AOP实践:

YII2框架本身拥有一个功能,叫做行为.它可以动态的为当前的类附加额外的功能,但这种功能在代码层级结构是静态的,有侵入性的。

下面以YII2框架集成go!aop库为例,介绍在YII2中如何实现AOP编程.(go!aop简介,可以参考go!aop的官网.)

由于YII框架拥有自己的类加载器,所在集成go!aop的时候,不能正常的工作,所以要将其禁用掉,使用composer提供的类加载器。

如下代码所示(这里使用YII2高级应用模板):

1、找到  spl_autoload_register(['Yii', 'autoload'], true, true);  (PROJECT_PATH/vendor/yiisoft/yii2/Yii.php) 将其禁用掉.

2、执行  composer require goaop/framework

3、修改composer.json文件,加入如下代码段:

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

4、 在frontend 目录下创建一个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,并使其实现BootstrapInterface,使其可以在YII2框架引导时被自动引导

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数组下新增一个key,代码如下:

 &#39;components&#39;=>[
        &#39;aop&#39; => [
            &#39;class&#39; => &#39;frontend\components\InitAopComponent&#39;
        ]
    ]

 
10、修改frontend/config/main.php文件,并在bootstrap数组下新增aop值,代码如下:

&#39;bootstrap&#39;=>[&#39;log&#39;,&#39;aop&#39;]

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

相关推荐:

关于IIS下PHP快三平台源码的架设环境的配置过程

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

以上がYII2 はアスペクト指向プログラミングを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。