Java 中的動態(tài)代理
源碼分析實現(xiàn)原理的過程:
http://blog.csdn.net/bluetjs/article/details/52263410
步驟:
必須要有一個接口吉殃, Subject
有一個類實現(xiàn)接口坦敌,RealSubject
實現(xiàn) InvocationHandler 接口夭拌,書寫代理類的邏輯
通過
Proxy.newProxyInstance
方法創(chuàng)建代理對象
代碼:
package com.interview.reflect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
Subject s = new RealSubject();
Subject subject = (Subject) Proxy.newProxyInstance(s.getClass().getClassLoader(),
s.getClass().getInterfaces(), new ProxyHandler<Subject>(s));
subject.method();
subject.dream();
}
}
interface Subject {
void method();
void dream();
}
class RealSubject implements Subject {
@Override
public void method() {
System.out.println("method run...");
}
@Override
public void dream() {
System.out.println("dream come true...");
}
}
class ProxyHandler<T> implements InvocationHandler {
private T target;
public ProxyHandler(T target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before invoke method process<<<<");
method.invoke(target, args);
System.out.println("after method invoke process>>>>>>");
return target;
}
}
運(yùn)行結(jié)果
before invoke method process
method run...
after method invoke process
before invoke method process
dream come true...
after method invoke process
底層實現(xiàn)
JDK提供了sun.misc.ProxyGenerator.generateProxyClass(String proxyName,class[] interfaces) 底層方法來產(chǎn)生動態(tài)代理類的字節(jié)碼延旧,這是 proxy 的底層實現(xiàn)
仔細(xì)觀察可以看出生成的動態(tài)代理類有以下特點(diǎn):
繼承自 java.lang.reflect.Proxy,實現(xiàn)了目標(biāo)類需要實現(xiàn)的接口
類中的所有方法都是 final 的
所有的方法功能的實現(xiàn)都統(tǒng)一調(diào)用了 InvocationHandler 的 invoke() 方法
cglib 的動態(tài)代理
Java 的動態(tài)代理的缺點(diǎn)是類必須要實現(xiàn)接口斗躏,如果沒有實現(xiàn)接口則無法產(chǎn)生代理贷币。為了應(yīng)對這種情況简烘,于是就產(chǎn)生了 cglib 的動態(tài)代理。
cglib 創(chuàng)建某個類A的動態(tài)代理類的模式是:
查找A上的所有非final 的public類型的方法定義
將這些方法的定義轉(zhuǎn)換成字節(jié)碼
將組成的字節(jié)碼轉(zhuǎn)換成相應(yīng)的代理的class對象
實現(xiàn) MethodInterceptor接口甩恼,用來處理 對代理類上所有方法的請求(這個接口和JDK動態(tài)代理InvocationHandler的功能和角色是一樣的)
其他的字節(jié)碼工具
javaassist蟀瞧,asm