Java動的プロキシ

高洛峰
リリース: 2016-12-01 13:30:52
オリジナル
1338 人が閲覧しました

1. 動的プロキシの導入

package cn2;
 
public interface IUserDAO {
    /**
     * 登录方法
     */
    public void login();
     
    /**
     * 注册方法
     */
    public void register();
 
}
package cn2;
 
public class UserDAOImpl implements IUserDAO {
 
    @Override
    public void login() {
        System.out.println("用户登录");
 
    }
 
    @Override
    public void register() {
        System.out.println("用户注册");
    }
 
}
package cn2;
 
public class Test {
    public static void main(String[] args) {
        IUserDAO dao = new UserDAOImpl();
        dao.register();
        dao.login();
         
         
    }
}
ログイン後にコピー

ユーザー登録

ユーザーログイン


各メソッドに権限の検証とログを追加する場合のコード実装は次のとおりです:

package cn2;
 
public interface IUserDAO {
    /**
     * 登录方法
     */
    public void login();
     
    /**
     * 注册方法
     */
    public void register();
 
}
package cn2;
 
public class UserDAOImpl implements IUserDAO {
 
    @Override
    public void login() {
        System.out.println("用户登录");
 
    }
 
    @Override
    public void register() {
        System.out.println("用户注册");
    }
 
}
package cn2;
 
public class UserDAOImpl2 implements IUserDAO {
    private void actionCheck(){
        System.out.println("权限检查");
    }
     
    private void record(){
        System.out.println("日志记录");
    }
     
    @Override
    public void login() {
        this.actionCheck();
        System.out.println("登录");
        this.record();
 
    }
 
    @Override
    public void register() {
        this.actionCheck();
        System.out.println("注册");
        this.record();
    }
 
}
package cn2;
 
public class Test {
    public static void main(String[] args) {
        IUserDAO dao = new UserDAOImpl2();
        dao.register();
        dao.login();
         
         
    }
}
ログイン後にコピー

権限チェック

登録

ロギング

権限チェック

ログイン

ロギング


インターフェイスを実装し、権限の検証とロギングを追加するために別のクラスを作成する必要があるのはなぜですか?なぜなら、設計する際には、拡張機能を開発し、コードの変更をクローズするという原則を確保する必要があるからです。元の実装クラスを変更するのではなく、元のインターフェイスの機能を拡張するために、インターフェイスを実装するための新しいクラスを定義しました。

しかし、このように設計すると大変なことになります。要件が変わると、多くの実装クラスを定義する必要があり、複雑すぎます。何をするか?


人生においては、「家を借りたいけど、家主が分からない、どうしたらいいの?」など、様々な問題に遭遇します。エージェントを見つけてください。同様に、権限チェックやログ機能を追加するためにコードを変更したくない場合は、実装に役立つプロキシ オブジェクトを見つけるだけでよいでしょうか?

動的プロキシ: このオブジェクトはプログラムの実行中に生成されます。

Javaでは、java.lang.reflectパッケージの下にProxyクラスとInvocationHandlerインターフェースが提供されており、このクラスとインターフェースを利用することで動的プロキシオブジェクトを生成することができます。 JDK はインターフェイスのプロキシとしてのみ機能します。

Proxyクラスのメソッドは動的プロキシオブジェクトを作成します

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
ログイン後にコピー

InvocationHandlerのメソッドは最終的に呼び出されます

Object invoke(Object proxy,Method method,Object[] args)
ログイン後にコピー
package cn2;
 
public interface IUserDAO {
    /**
     * 登录方法
     */
    public void login();
     
    /**
     * 注册方法
     */
    public void register();
 
}
package cn2;
 
public class UserDAOImpl implements IUserDAO {
 
    @Override
    public void login() {
        System.out.println("用户登录");
 
    }
 
    @Override
    public void register() {
        System.out.println("用户注册");
    }
 
}
package cn2;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class MyInvocationHandler implements InvocationHandler {
     
    private Object target;
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
     
    /**
     *返回动态代理对象
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
         
        System.out.println("权限检查");
         
        Object invoke = method.invoke(target, args);
         
        System.out.println("日志记录");
        return invoke;
    }
 
}
package cn2;
 
import java.lang.reflect.Proxy;
 
public class Test {
    public static void main(String[] args) {
        //使用动态代理之前
        IUserDAO dao = new UserDAOImpl();
        dao.register();
        dao.login();
         
        System.out.println("-------------------");
         
        //使用动态代理之后
         
        IUserDAO proxy = (IUserDAO)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new MyInvocationHandler(dao));
        proxy.register();
        proxy.login();
         
    }
}
ログイン後にコピー

ユーザー登録

ユーザーログイン

-------- -- ---------

権限チェック

ユーザー登録

ロギング

権限チェック

ユーザーログイン

ロギング


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート