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(); } }
ユーザー登録
ユーザーログイン
-------- -- ---------
権限チェック
ユーザー登録
ロギング
権限チェック
ユーザーログイン
ロギング