JavaWeb之動態代理
動態代理通俗解釋:
A介面有c方法,類B實現A介面,原本應該是執行B類中的c方法,可現在不這樣做,可以先宣告產生B類的代理類B`,由它來冒充B類的“兄弟”並“實現”A介面, 對外界來說B`應該也有c方法,可當真正呼叫它的時候, 它會去執行與它關聯InvocationHandler的invoke()方法, 在這個方法裡面你可以做很多事情。
Java怎樣實現動態代理呢
第一步,我們要有一個介面,還要有一個介面的實現類,而這個實現類就是我們要代理的類。
public interface Subject
{
public void request();
}
public class RealSubject implements Subject
{
public void request()
{
System.out.println("From real subject!");
}
}
第二步,我們要自己寫一個代理類,它的特點是實現了InvocationHandler介面, 因為代理類的例項在呼叫實現類的方法的時候,不是去呼叫真正的實現類的這個方法, 而是呼叫代理類的invoke()方法,在這個方法中才呼叫真正的實現類的方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 該代理類的內部屬性是Object型別,實際使用的時候通過該類的構造方法傳遞進來一個物件
* 此外,該類還實現了invoke方法,該方法中的method.invoke其實就是呼叫被代理物件的將要
* 執行的方法,方法引數是sub,表示該方法從屬於sub,通過動態代理類,我們可以在執行真實物件的方法前後
* 加入自己的一些額外方法,這裡在方法呼叫前後列印一句話。
*
*/
public class DynamicSubject implements InvocationHandler
{
private Object sub;
public DynamicSubject(Object obj)
{
this.sub = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println("before calling: " + method);
method.invoke(sub, args);
System.out.println(args == null);
System.out.println("after calling: " + method);
return null;
}
}
上述方法體中method.invoke(owner, args)的解釋:執行該method.invoke方法的引數是執行這個方法的物件owner,引數陣列args,可以這麼理解:owner物件中帶有引數args的method方法。返回值是Object,也就是該方法的返回值。
第三步,客戶端要用代理類的例項去呼叫實現類的方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client
{
public static void main(String[] args)
{
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new DynamicSubject(realSubject);
Class<?> classType = handler.getClass();
// newProxyInstance()動態生成一個類並載入到記憶體
// 載入到記憶體要使用載入器,第一個引數是一個類載入器
Subject subject = (Subject) Proxy.newProxyInstance(classType
.getClassLoader(), realSubject.getClass().getInterfaces(),
handler);
subject.request();
System.out.println(subject.getClass());
}
}
對第三步的解釋
主要是以下程式碼:
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
該方法主要做了如下工作:
- 根據引數loader和interfaces呼叫方法 getProxyClass(loader, interfaces) 建立代理類$Proxy0,該代理類實現了預先定義的介面(如上面的Subject),並繼承了Proxy類。
public final class $Proxy0 extends Proxy implements Subject
-
例項化$Proxy0(建立代理物件)並在構造方法中把 InvocationHandler(這裡handler 是它的例項)傳過去
-
$Proxy0呼叫父類Proxy的構造器,為InvocationHandler 賦值:
public $Proxy0(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
========================================================
class Proxy
{
protected InvocationHandler h;
protected Proxy(InvocationHandler h)
{
this.h = h;
}
}
- 將這個$Proxy0類強制轉型成介面型別,當執行介面中的方法時(如上文強轉成Subject後呼叫request()方法),就呼叫了$Proxy0類中實現的介面方法,在該方法中會呼叫父類Proxy中的invoke()方法,即InvocationHandler.invoke(),達到做一些其他工作的效果。
public final void request()
{
try
{
//m是通過反射得到的方法名 Method型別
super.h.invoke(this, m, null);
return;
}
catch (Error e)
{
}
catch (Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
相關文章
- AOP之靜態代理VS動態代理
- AOP之動態代理
- 【JAVA】代理模式之Java動態代理Java模式
- PHP 反射之動態代理PHP反射
- Java Web之動態代理JavaWeb
- Java進階之 JDK動態代理與Cglib動態代理JavaJDKCGLib
- Java設計模式-之代理模式(動態代理)Java設計模式
- Java代理(jdk靜態代理、動態代理和cglib動態代理)JavaJDKCGLib
- 靜態代理和動態代理
- 代理模式詳解:靜態代理、JDK動態代理與Cglib動態代理模式JDKCGLib
- 代理模式 - 動態代理模式
- java靜態代理和動態代理Java
- 動態代理
- Java代理之靜態代理Java
- 設計模式之cglib動態代理設計模式CGLib
- JDK動態代理JDK
- 動態代理模式模式
- java動態代理Java
- java反射之動態代理學習筆記Java反射筆記
- 23種設計模式之——動態代理模式設計模式
- java動態代理動態在哪裡?Java
- 輕鬆理解 Java 靜態代理/動態代理Java
- 3.靜態代理&動態代理&CGlibCGLib
- Java中的靜態代理和動態代理Java
- 靜態代理、動態代理與Mybatis的理解MyBatis
- Android 動態代理以及利用動態代理實現 ServiceHookAndroidHook
- 深入理解靜態代理與JDK動態代理JDK
- Java基礎系列-靜態代理和動態代理Java
- JAVA學習篇--靜態代理VS動態代理Java
- Java動態程式設計---動態代理Java程式設計
- spring aop原理 JDK動態代理和CGLIB動態代理SpringJDKCGLib
- JDK動態代理和 CGLIB 代理JDKCGLib
- JDK動態代理和CGLib代理JDKCGLib
- Java動態代理(AOP)Java
- CGLib 動態代理CGLib
- Spring 動態代理Spring
- JDK動態代理初探JDK
- java動態代理(1)Java