?參考?http://www.iteye.com/topic/683613
參考?http://hi.baidu.com/malecu/item/9e0edc115cb597a1feded5a0
參考 http://www.educity.cn/wenda/360356.html
參考?http://langyu.iteye.com/blog/410071
?
/**
* 相親接口
*
* @author zhengt
* @time Jun 3, 2095 3:13:03 PM
*/
public interface XiangQinInterface {
/**
* 相親方法
*/
public void xiangQin();
}
/**
* 張三相親實(shí)現(xiàn)類
*
* @author zhengt
* @time Jun 3, 2095 3:14:48 PM
*/
public class ZhangSanXiangQinInterfaceImpl implements XiangQinInterface {
public void xiangQin() {
System.out.println("張三去相親,娶個(gè)漂亮老婆。");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 相親可是一輩子的大事,相親前要準(zhǔn)備一下,打扮得帥氣些。
*
* @author zhengt
* @time Jun 3, 2095 3:15:48 PM
*/
public class ReadyInvocationHandler implements InvocationHandler {
//相親接口的實(shí)現(xiàn)類,也就是張三相親類
private Object zhangSan = null;
public ReadyInvocationHandler(Object realSubject) {
this.zhangSan = realSubject;
}
public Object invoke(Object proxy, Method m, Object[] args) {
Object result = null;
try {
/**
* 動態(tài)代理類$Proxy0調(diào)用xiangQin方法時(shí)會調(diào)用它自己的xiangQin方法,
* 而它自己的xiangQin方法里面調(diào)用的是super.h.invoke(this, , ),也就是父類Proxy的h的invoke方法,
* 也就是ReadyInvocationHandler類的invoke方法。
* 所以,invoke(Object proxy, Method m, Object[] args)種的proxy實(shí)際上就是動態(tài)代理類$Proxy0,
* 如果你將其強(qiáng)轉(zhuǎn)成XiangQinInterface然后調(diào)用它的xiangQin方法,然后它就會調(diào)用super.h.invoke(this, , ),這樣就會死循環(huán)。
*/
/**
* 網(wǎng)上關(guān)于這里最多問題就是Object proxy放在這里用來做什么呢?這個(gè)我也不知道,
* 不過至少我們知道它到底是個(gè)什么東西,具體做什么用嘛就不得而知了
*/
System.out.println(proxy.getClass().getSimpleName());
System.out.println("張三相親前,代理人給他打扮了打扮。");
result = m.invoke(zhangSan, args);
} catch (Exception ex) {
System.exit(1);
}
return result;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 張三來到了婚介所(相親現(xiàn)場),開始相親。
*
* @author zhengt
* @time Jun 3, 2095 3:17:16 PM
*/
public class HunJieSuo {
public static void main(String args[]) {
//先將張三相親這個(gè)相親的實(shí)現(xiàn)類實(shí)例化,也就是得到XiangQinInterface接口的一個(gè)實(shí)例對象
XiangQinInterface zhangSan = new ZhangSanXiangQinInterfaceImpl();
/**
* 得到ZhangSanXiangQinInterfaceImpl這個(gè)類的一個(gè)代理類,同時(shí)為代理類綁定了一個(gè)處理類ReadyInvocationHandler。
* 聽著很繞口,其實(shí)就是每次調(diào)用ZhangSanXiangQinInterfaceImpl這個(gè)子類的xiangQin方法時(shí),
* 不是zhangSan這個(gè)ZhangSanXiangQinInterfaceImpl類的實(shí)例去調(diào)用,
* 而是這個(gè)ZhangSanXiangQinInterfaceImpl的代理類ReadyInvocationHandler去調(diào)用它自己的invoke方法,
* 這個(gè)invoke方法里呢可以調(diào)用zhangSan這個(gè)實(shí)例的xiangQin方法
*/
/**
* 在java種怎樣實(shí)現(xiàn)動態(tài)代理呢
* 第一步,我們要有一個(gè)接口,還要有一個(gè)接口的實(shí)現(xiàn)類,而這個(gè)實(shí)現(xiàn)類呢就是我們要代理的對象,
* 所謂代理呢也就是在調(diào)用實(shí)現(xiàn)類的方法時(shí),可以在方法執(zhí)行前后做額外的工作,這個(gè)就是代理。
* 第二步,我們要自己寫一個(gè)在要代理類的方法執(zhí)行時(shí),能夠做額外工作的類,而這個(gè)類必須繼承InvocationHandler接口,
* 為什么要繼承它呢?因?yàn)榇眍惖膶?shí)例在調(diào)用實(shí)現(xiàn)類的方法的時(shí)候,不會調(diào)真正的實(shí)現(xiàn)類的這個(gè)方法,
* 而是轉(zhuǎn)而調(diào)用這個(gè)類的invoke方法(繼承時(shí)必須實(shí)現(xiàn)的方法),在這個(gè)方法中你可以調(diào)用真正的實(shí)現(xiàn)類的這個(gè)方法。
* 第三步,在要用代理類的實(shí)例去調(diào)用實(shí)現(xiàn)類的方法的時(shí)候,寫出下面兩段代碼。
*/
// 獲得代理類($Proxy0 extends Proxy implements XiangQinInterface)的實(shí)例.
XiangQinInterface proxy = (XiangQinInterface) Proxy.newProxyInstance(
zhangSan.getClass().getClassLoader(),
zhangSan.getClass().getInterfaces(),
new ReadyInvocationHandler(zhangSan));
proxy.xiangQin();
/**
* 這里要解釋下中部那段長長的代碼的意思,以及具體做了哪些工作?
* 第一,根據(jù)zhangSan.getClass().getClassLoader()這個(gè)要代理類的類加載器和
* zhangSan.getClass().getInterfaces()要代理類所實(shí)現(xiàn)的所有的接口
* 作為參數(shù)調(diào)用Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces)
* 的方法返回代理類的java.lang.Class對象,也就是得到了java動態(tài)生成的代理類$Proxy0的Class對象。
* 同時(shí),java還讓這個(gè)動態(tài)生成的$Proxy0類實(shí)現(xiàn)了要代理類的實(shí)現(xiàn)的所有接口,并繼承了Proxy接口。
* 第二,實(shí)例化這個(gè)動態(tài)生成的$Proxy0類的一個(gè)實(shí)例,實(shí)例化代理類的構(gòu)造函數(shù)為Proxy(InvocationHandler h),
* 也就是說要實(shí)例化這個(gè)動態(tài)生成的$Proxy0類,必須給它一個(gè)InvocationHandler參數(shù),也就是我們自己實(shí)現(xiàn)的用來在代理類
* 方法執(zhí)行前后做額外工作的類ReadyInvocationHandler。
* 這段代碼Proxy.newProxyInstance(zhangSan.getClass().getClassLoader(),zhangSan.getClass().getInterfaces(),new ReadyInvocationHandler(zhangSan))
* 得到的其實(shí)是一個(gè)類名叫$Proxy0 extends Proxy implements XiangQinInterface的類。
* 第三,將這個(gè)$Proxy0類強(qiáng)制轉(zhuǎn)型成XiangQinInterface類型,調(diào)用xiangQin方法。
*/
}
}
?
備注:著重看“ // 獲得代理類($Proxy0 extends Proxy implements XiangQinInterface)的實(shí)例. ”這個(gè)注解 。?
?一.相關(guān)類及其方法:
java.lang.reflect.Proxy,
Proxy 提供用于創(chuàng)建動態(tài)代理類和實(shí)例的靜態(tài)方法 .
newProxyInstance()
返回一個(gè)指定接口的代理類實(shí)例,該接口可以將方法調(diào)用指派到指定的調(diào)用處理程序
(詳見api文檔)
?
java.lang.reflect.InvocationHandler,
InvocationHandler 是代理實(shí)例的調(diào)用處理程序 實(shí)現(xiàn)的接口 。?
invoke()
在代理實(shí)例上處理方法調(diào)用并返回結(jié)果。在與方法關(guān)聯(lián)的代理實(shí)例上調(diào)用方法時(shí),將在調(diào)用處理程序上調(diào)用此方法。
?
創(chuàng)建某一接口 Foo 的代理:?
?
InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass(
Foo.class.getClassLoader(), new Class[] { Foo.class });
Foo f = (Foo) proxyClass.
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
?
?
或使用以下更簡單的方法:?
?
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
?
?
四.機(jī)制分析:
Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下幾件事.
(1)根據(jù)參數(shù)loader和interfaces調(diào)用方法 getProxyClass(loader, interfaces)創(chuàng)建代理類$Proxy.
$Proxy0類實(shí)現(xiàn)了interfaces的接口,并繼承了Proxy類.
?
(2)實(shí)例化$Proxy0并在構(gòu)造方法中把BusinessHandler傳過去,接著$Proxy0調(diào)用父類Proxy的構(gòu)造器,為h賦值,如下:
class Proxy{
InvocationHandler h=null;
protected Proxy(InvocationHandler h) {
this.h = h;
}
...
}
?
?
下面是本例的$Proxy0類的源碼(好不容易才把它提出來):
?
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements
XiangQinInterface
{
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);
m3 = Class.forName("com.ml.test.Manager").getMethod("modify",
new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString",
new Class[0]);
} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}
@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
.booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final void modify() {
try {
super.h.invoke(this, m3, null);
return;
} catch (Error e) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}
?
?
?
接著把得到的$Proxy0實(shí)例強(qiáng)制轉(zhuǎn)換成XiangQinInterface?.
當(dāng)執(zhí)行proxy.xiangQin()方法時(shí),就調(diào)用了$Proxy0類中的xiangQin()方法.
在modify方法中,調(diào)用父類Proxy中的h的invoke()方法.
即InvocationHandler.invoke();?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

