動的プロキシ
jdk プロキシ -- インターフェイス プロキシに基づく
cglib -- クラスベースのプロキシ
javassist – バイトコードに基づく
jdk 動的プロキシ クラスはインターフェイスを表し、通常はビジネスに属します。ソースコードを変更することなく、追加の処理変更を低コストで簡単に行うことができます。
jdk プロキシは主に、java.lang.reflect パッケージの Proxy クラスと InvacationHandler インターフェイスを通じて実装されます。まず、これら 2 つのクラスのソース コードを見てください。
InvacationHandler インターフェース
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
呼び出しメソッドは 1 つだけです。このメソッドはプロキシ インスタンスを処理し、結果を返します。これは、リフレクション メソッド、method.invoke(Object obj, Object[] args) を使用して呼び出す必要があります。最初のパラメータは、プロキシされるインターフェイス クラスです。2 つ目は、対応するメソッドに関連するパラメーターです。
ソース コードに戻ると、最初のパラメータは理論的にはプロキシされるオブジェクトですが、実際には使用されません。2 番目のパラメータはインターフェイス内の対応するメソッド、3 番目のパラメータは対応するパラメータです。
次に、Proxy クラスを見てください。
重要で一般的に使用されるメソッドが含まれています
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
対応するプロキシ クラスのインスタンスを取得します。このメソッドは通常、プロキシ インスタンスを動的に取得するために使用されます。
JDKプロキシを使用する手順
1. インターフェイス InvocationHandler を実装するクラスを作成します。これは、invoke メソッドを実装する必要があります。
2. プロキシ クラスとインターフェイスを作成します。
3. プロキシの静的メソッド
newProxyInstance(ClassLoaderloader, Class[] Interfaces, InvocationHandler h) を使用してプロキシを作成します
。 4.プロキシ呼び出しメソッド
の実装コード:
実際の役割 (プロキシされるオブジェクト):
package com.heaboy.proxyExcise.JDkProxy;
/**
* @Author:XK
* @Date: Created in 11:23 2022/2/19
* @Description:
**/
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东出租房子");
}
@Override
public void run() {
System.out.println("房东跑了");
}
}
抽象的な役割 (プロキシされるインターフェース)
package com.heaboy.proxyExcise.JDkProxy;
/**
* @Author:XK
* @Date: Created in 11:20 2022/2/19
* @Description:
**/
public interface Rent {
public void rent();
public void run();
}
InvacationHanlerの役割を継承し、プロキシオブジェクトを動的に生成する
package com.heaboy.proxyExcise.JDkProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author:XK
* @Date: Created in 15:45 2022/2/19
* @Description:
**/
public class RentProxy implements InvocationHandler {
private Rent target;
public RentProxy(Rent target) {
this.target = target;
}
//动态生成代理对象
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
//处理实例的方法,并且加以附属操作
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
Object result=method.invoke(target,args);
fare();
return result;
}
public void seeHouse(){
System.out.println("中介带你去看房");
}
public void fare(){
System.out.println("中介带你收费");
}
}
顧客の役割、通話エージェント
package com.heaboy.proxyExcise.JDkProxy;
/**
* @Author:XK
* @Date: Created in 15:52 2022/2/19
* @Description:
**/
public class client {
public static void main(String[] args) {
Host host = new Host();
RentProxy rentProxy = new RentProxy(host);
Rent proxy = (Rent)rentProxy.getProxy();
//proxy.rent();
proxy.run();
}
}