Springbootエージェント工場


エージェントファクトリ(Springでサポートされているエージェント)


動的エージェントの問題
  • インタフェースがある場合、JDKダイナミックエージェントをどのように適用しますか?そうでない場合、CGIBを適用しますか?
  • を同時に使用する場合は、重複作成と管理が必要ですか?
  • 特定の条件を満たすときにエージェントロジックを適用する機能も共通であり、
  • .

    代理工場


    Springは、動的エージェントを統合することで容易に作成できるエージェントファクトリと呼ばれる機能を提供します.
    エージェントファクトリにインタフェースがある場合はJDKダイナミックエージェントを使用し,具体的なクラスのみCGIBをサポートする.
    クライアントがエージェントファクトリを要求すると、エージェントファクトリは状況に応じてjdkダイナミックエージェントまたはCGIB特定のクラスエージェントに戻ります.
  • 付加機能はそれぞれ繰り返し作成する必要がありますか?
    Springは付加機能を適用する際に「advice」という新しい概念を導入してこの問題を解決した.
    開発者は「Advice」を作成するだけで、InvocationHandlerやMethodInterceptorに関心を持つ必要はありません.
  • はまた、特定の条件を満たすときにエージェントロジックを適用する機能を提供する.このときスプリングに「Pointcut」を使えばいいです.
  • メソッドインタフェースはデバイス名と同じなので、パッケージをよく確認してください.
  • org.aopalliance.ブロックしています.
  • 
     ServiceInterface target = new ServiceImpl();
            //여기서 프록시를 만들때 타캣을 넣어준다.
            ProxyFactory proxyFactory = new ProxyFactory(target);
            proxyFactory.addAdvice(new TimeAdvice());
            ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy();
            proxy.save();
            //프록시팩토리를 사용할 때만 사용가능
            assertThat(AopUtils.isAopProxy(proxy)).isTrue();
            assertThat(AopUtils.isJdkDynamicProxy(proxy)).isTrue();
            assertThat(AopUtils.isCglibProxy(proxy)).isFalse();
    
    proxyFactory.getProxy():エージェントオブジェクトを作成し、結果を受信します.
    これにより、クラス情報をインスタンスに直接出力して検証することもできます.getClass();

    エージェントファクトリのテクノロジーの選択方法

  • ターゲットにインタフェースがある場合:JDK動的エージェント、インタフェース基本エージェント
  • ターゲットにインタフェース:CGIBがない場合、特定のクラスに基づくエージェント
  • "ProxyTargetClass=True":CGIBクラスベースのエージェントで、インタフェースを考慮する必要はありません

    整理する


    エージェントファクトリのサービス抽象化により、特定のエージェント技術に依存することなく、動的エージェントを容易に作成できます.
    これは内部にハンドルがあるからです.

    リファレンス


    AOPを適用すると、スプリングガイドのデフォルト設定は「ProxyTargetClass=true」です.
    したがって,インタフェースがあっても,CGIBを用いて特定のクラスからエージェントを生成することが多い.

    アクセントレンズ

  • ドットカット:どこで付加機能を適用するか、どこで付加機能を適用しないかを判断するフィルタロジック.主にクラスとメソッド名でフィルタされます.
    すなわち,ある点に名前で機能を適用しなければ区別する.
  • デバイス:前述したように、エージェント呼び出しの追加機能である.
  • は単純なエージェントロジックのようです
  • 通話員:簡単に言えば、重点レンズと通話員です.
  • たとえば、追加機能ロジックを適用する必要がある場合は、ポイントカットとして適用する場所を選択します.
    デバイスとしてどの論理を適用するかを選択します.
    どこにいても、どんな論理でも、知っているのは助け者です.

    役割と責任


    このように分ける理由は、役割と責任を明確に区別しているからです.
  • ダイカットは、対象の有無を確認するフィルタのみを担当します.
  • デバイスは、追加機能ロジックのみをきれいに担当します.
  • 通話員は以上の2つの機能を担当します.
  • 使用例

    ServiceInterface target = new ServiceImpl();
            ProxyFactory proxyFactory = new ProxyFactory(target);
    
            DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(Pointcut.TRUE, new TimeAdvice());
            proxyFactory.addAdvisor(advisor);
            ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy();
            proxy.save();
            proxy.find();
    
  • DefaultPointAdvisor:Advisorインタフェースの最も一般的な実装.ジェネレータにドットカットとヒントを追加すればいいです.
  • Pointcut.TRUE:常にtrueの積分カットを返します.
  • proxyFactory.addAdvisor(advisor):エージェントファクトリに適用するコンサルタントを指定します.
    通話員は内部に重点レンズと通話員がある.そのため、どのような付加機能をどこで適用すべきかは、1つのヒントしかありません.
    エージェントファクトリを使用する場合は、コンサルタントが必要です.
  • スプリングによるポイントカット


    スプリングは無数の点切り欠きを提供します.
    代表的なポイント
  • NameMatchMethodPointcut:メソッド名に基づいて一致します.
  • JdkRegexpMethodPointcut:JDK正規表現に基づいてポイントカットをマッチングします.
  • TruePointcut:常に斬り返します.
  • AnnotationMatchingPointcut:Annotationと呼ばれます.
  • AspectJexpressionPointcut:AspectJ式に一致する
  • 最も重要なのはaspectJ式です


    ここでは、
    AspectJExpressionPointcutが使用されます.

    複数のコンサルタントを同時に適用


    通話員には重点レンズと通話員がいます.複数のコンサルタントを1つのtargetに適用するには、次の手順に従います.
    複数のエージェントを作成する方法はありますが、よくありません.
    @Test
        @DisplayName("하나의 프록시 여러 어드바이저")
        void multiAdvisorTest2(){
            //client -> proxy->advisor1 -> advisor2 -> target
            //여러 어드바이저 적용
            //이때 각 어드바이저의 포인트컷이 적용된상태로 실행된다.
            DefaultPointcutAdvisor advisor1 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice1());
            DefaultPointcutAdvisor advisor2 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice2());
    
            //프록시 1 생성
            ServiceInterface target = new ServiceImpl();
            ProxyFactory proxyFactory1 = new ProxyFactory(target);
            //순서대로 동작
            proxyFactory1.addAdvisor(advisor2);
            proxyFactory1.addAdvisor(advisor1);
    
            ServiceInterface proxy1 = (ServiceInterface) proxyFactory1.getProxy();
    
            //실행
            proxy1.save();

    重要


    Spring AOPを初めて学習または適用すると,生成されたエージェントの数がアプリケーションAOPの数と同じであると勘違いする.
    スプリングはAOPを適用する際に最適化され,現在のように1つのエージェントのみが作成され,1つのエージェントに複数のウィザードが適用される.
    複数のAPを1つのターゲットに同時に適用すると、スプリングはターゲットごとにプロキシを作成します.
    つまり、その中に様々なコンサルタントが加わる.

    質問する

  • 構成が多すぎます
    たとえば、アプリケーションにスプリングが100個ある場合は、エージェントを介して100個以上の追加機能を提供するには、100個の動的エージェントを作成する必要があります.
  • 素子スキャン
    素子スキャンを行うと、以上の方法は不可能である.エージェントはスプリングシートに登録されているため、スキャンされたコンポーネントの実際のオブジェクトを登録するときに使用できません.
  • この問題を解決するには、空のポストプロセッサを知る必要があります。