AndroidでJavaを使用した動的エージェント

4316 ワード

同僚が機能を書くときにJavaのダイナミックエージェントを使っていたので、その機能を実現するときにこの技術を使うことには賛成しませんが、Androidでのダイナミックエージェントの役割を無視することはできません.
例えば,多くのプラグイン化フレームワークは動的エージェントを原理としている.Androidプラグイン化原理解析——Hookメカニズムの動的エージェント
そこでjavaエージェントに関する知識を簡単に紹介します.
1.Javaのプロキシモード
定義:このオブジェクトへのアクセスを制御するプロキシを他のオブジェクトに提供します.
はっきり言って、1つのオブジェクトが修正しにくい場合、newの新しいエージェントオブジェクトを通じて彼を制御することができて、しかも簡単にいくつかの新しい方法と特性を加えることができます.
Javaのエージェント技術は一般的に3種類に分けられ,静的エージェント,動的エージェント,Cglibエージェントである.
2.静的エージェント
静的エージェントは比較的簡単で,次のコードを見るとよく理解できる.
//      
public interface Interface {
    void doSomething();

    void somethingElse(String args);
}
//         
public class RealObject implements Interface {

    @Override
    public void doSomething() {
        System.out.println("doSomething");
    }

    @Override
    public void somethingElse(String args) {
        System.out.println("somethingElse" + args);
    }
}

//      
public class SimpleProxy implements Interface {
    //           
    private Interface proxied;
    //       
    public SimpleProxy(Interface proxied) {
        this.proxied = proxied;
    }

    //    
    @Override
    public void doSomething() {
        System.out.println("SimpleProxy doSomething");
        proxied.doSomething();

    }

    @Override
    public void somethingElse(String args) {
        System.out.println("SimpleProxy somethingElse" + args);
        proxied.somethingElse(args);
    }
}
//    
public class SimpleProxyDemo {

    public static void consumer(Interface iface) {
        iface.doSomething();
        iface.somethingElse(":jyu");
    }

    public static void main(String[] args) {
        consumer(new RealObject());
        consumer(new SimpleProxy(new RealObject()));
    }
}


出力:
doSomething
somethingElse:jyu
SimpleProxy doSomething
doSomething
SimpleProxy somethingElse:jyu
somethingElse:jyu

ダイナミックエージェント
動的エージェントはJDKエージェント、インタフェースエージェントとも呼ばれます.ターゲットオブジェクトのインタフェースを実装する必要はありません.JavaのAPIを使用してプロキシオブジェクトを生成し、メモリ内のコンポーネントプロキシオブジェクトを動的に生成します(プロキシオブジェクト/ターゲットオブジェクトを作成するインタフェースのタイプを指定する必要があります).
次の例を見てみましょう.やはり上のInterfaceインタフェースとRealObjectクラスを使用します.
//  InvocationHandler  
public class DynamicProxyHandler implements InvocationHandler {

    private Object proxied;

    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    //  invoke  
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("*** proxy:" 
        + proxy.getClass() + ",
method:" + method + ",
args:" + args); if (args != null) { for (Object arg : args) { System.out.println(" " + arg); } } return method.invoke(proxied, args); } }
//    
public class SimpleDynamicProxy {

    public static void consumer(Interface iface) {
        iface.doSomething();
        iface.somethingElse(" jyu");
    }

    public static void main(String[] args) {
        RealObject real = new RealObject();
        consumer(real);

        Interface proxy = (Interface) Proxy.newProxyInstance(
                Interface.class.getClassLoader(),
                new Class[]{Interface.class},
                new DynamicProxyHandler(real));
        consumer(proxy);
    }
}
//  :
doSomething
somethingElse jyu
*** proxy:class com.sun.proxy.$Proxy0,
method:public abstract void proxy.Interface.doSomething(),
args:null
doSomething
*** proxy:class com.sun.proxy.$Proxy0,
method:public abstract void proxy.Interface.somethingElse(java.lang.String),
args:[Ljava.lang.Object;@355da254
    jyu
somethingElse jyu


PS:『javaプログラミング思想』に残されたジョブ:動的エージェントを使用してトランザクションを実現するシステムを作成し、エージェントはエージェントの呼び出しによって実行に成功したとき(異常を投げ出さない)にコミットを実行し、その実行に失敗したときにロールバックを実行する.あなたのコミットとロールバックは、Java異常の制御制御範囲内ではない外部のテキストファイルに対して行われます.操作の原子性に注意しなければなりません
3.Cglibエージェント
cglibはandroidでは使用できないので、ここではこの技術について議論しません.興味のある学生は似たような文章を読むことができます.cglibダイナミックエージェント思想をAndroid開発に持ち込む
参考資料
  • 【Javaベース】動的エージェントによるAOPの制御トランザクション
  • の実装
  • java設計モード-プロキシモード(Proxy)