import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
/**
* 代理模式至少需要實現兩個類,一個代理類,一個被代理類(都要實現共有接口)。
* 動態代理之所以稱爲動態,是因爲代理類在運行時由Proxy類產生,
* 這就大大減少了需要我們手工設計代理類的數量。
*在實際應用中,Proxy通過類裝載器和需要實現的接口來產生代理類,
*即Proxy.getProxyClass(ClassLoader, Class[]),返回爲代理類的Class實例。
*一般而言,該方法由InvocationHandler的實現類中的方法來調用,
*可以取這樣的名字:getProxyObject,該方法使用Proxy.getProxyClass後
*(此時兩個入口參數可以用realObject.getClass.getClassLoader()
*以及realObject.getClass.getInterfaces()兩個方法得到,
*realObject指被代理類實例,一般由InvocationHandler的實現類的構造函數注入),
*進一步使用Class中的getConstructor(new Class[] { InvocationHandler.class}).newInstance(new Object[] { this })
*來得到代理類的實例(或者合併這兩個方法,
*用Proxy.newProxyInstance(realObject.getClass.getClassLoader(), realObject.getClass.getInterfaces(),this)方法)
*。但是必須注意代理類的實現是由Proxy完成,與InvocationHander的實現類毫無關係,
*InvocationHander的實現類只是通過代理類的構造函數注入後實現了對代理類中方法調用的攔截。
*InvocationHander的實現類需要保留一個指向被代理類的引用(或稱句柄、指針),
*該被代理類一般通過InvocationHandler的實現類的構造函數注入,也可以用set方法,
*一般可以取爲realObject。則在InvocationHandler接口的invoke方法中,
*對於realObject中相應方法的直接調用是用method.invoke(realObjet, args )實現的,
*其中method和args直接由invoke方法中的輸入參數給出。
*
*好了先讓我們倆瞭解什麼是代理
*/
//AOP面向切面的編程
public class BeanFactory {
//動態代理入門
public static void main(String[] args) throws Exception {
//首先我們先讓JVM生成一個代理類
Class clazzProsy = Proxy.getProxyClass(Collection.class
.getClassLoader(), Collection.class);
System.out.println(clazzProsy.getName());
System.out.println("-----Begin constructor-----");
//得到代理類上的構造函數
Constructor[] constructors = clazzProsy.getConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
// 單線程下StringBuilder效率比較高
// 多線程時StringBuffer效率比較高
StringBuilder strB = new StringBuilder(name);
strB.append('(');
Class[] clazzParams = constructor.getParameterTypes();
for (Class clazzParam : clazzParams) {
strB.append(clazzParam.getName()).append(',');
}
if (clazzParams.length != 0 && clazzParams != null)
strB.deleteCharAt(strB.length() - 1);
strB.append(')');
System.out.println(strB.toString());
}
System.out.println("-----Begin methods-----");
//得到代理類上的所有方法
Method[] methods = clazzProsy.getMethods();
for (Method method : methods) {
String name = method.getName();
// 單線程下StringBuilder效率比較高
// 多線程時StringBuffer效率比較高
StringBuilder strB = new StringBuilder(name);
strB.append('(');
Class[] clazzParams = method.getParameterTypes();
for (Class clazzParam : clazzParams) {
strB.append(clazzParam.getName()).append(',');
}
if (clazzParams.length != 0 && clazzParams != null)
strB.deleteCharAt(strB.length() - 1);
strB.append(')');
System.out.println(strB.toString());
}
}
}
什麼是動態代理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.