package com.itcast.day3;
import java.io.ObjectInputStream.GetField;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
/**
* 通過反射打印出 代理類的 構造函數、方法以及其參數列表
* @author liujl
*
*/
public class ProxyTest {
public static void main(String[] args) throws Exception{
Class clazzProxy=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy);
System.out.println("---------------begin constructors list-----------------");
Constructor[] constructors=clazzProxy.getConstructors();
for(Constructor constructor:constructors){
String name=constructor.getName();
StringBuilder sb=new StringBuilder(name);
sb.append("(");
Class[] clazzParams=constructor.getParameterTypes();
for(Class clazzParam:clazzParams){
sb.append(clazzParam.getName());
}
if(clazzParams!=null&&clazzParams.length!=0)
sb.deleteCharAt(sb.length()-1);
sb.append(")");
System.out.println(sb);
}
System.out.println("---------------begin methods list-----------------");
Method[] methods=clazzProxy.getMethods();
for(Method method:methods){
String name=method.getName();
StringBuilder sb=new StringBuilder(name);
sb.append("(");
Class[] clazzParams=method.getParameterTypes();
for(Class clazzParam:clazzParams){
sb.append(clazzParam.getName()).append(",");
}
if(clazzParams!=null&&clazzParams.length!=0)
sb.deleteCharAt(sb.length()-1);
sb.append(")");
System.out.println(sb);
}
System.out.println("---------------begin create instance object----------------");
// clazzProxy.newInstance();//這樣不行,這樣只會掉那個不帶參數的構造方法,而代理對象沒有無參構造
//第一種方式創建實例
Constructor constructor=clazzProxy.getConstructor(InvocationHandler.class);
class MyInvocationHander1 implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
Collection proxy1=(Collection) constructor.newInstance(new MyInvocationHander1());
System.out.println(proxy1.toString());
proxy1.clear();
// proxy1.size();//java.lang.NullPointerException
//第二種方式創建實例
Collection proxy2=(Collection)constructor.newInstance(new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
//第三種方式創建代理類的實例, 得到Class 和 創建實例對象 一步到位
Collection proxy3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler() {
ArrayList target=new ArrayList();//類變量
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
StringBuilder sbMethodAndParams=new StringBuilder();
sbMethodAndParams.append(method.getName()).append("(");
if(args!=null){
for(Object obj : args){
sbMethodAndParams.append(obj.toString()).append(",");
}
if(args!=null&&args.length!=0){
sbMethodAndParams.deleteCharAt(sbMethodAndParams.length()-1);
}
}
sbMethodAndParams.append(")");
System.out.println(sbMethodAndParams);
long beginTime=System.currentTimeMillis();
Object retVal=method.invoke(target, args);
long endTime=System.currentTimeMillis();
System.out.println(method.getName()+"執行時間 "+(endTime-beginTime)+" 毫秒");
return retVal;
}
});
proxy3.clear();
proxy3.add("ljl");
proxy3.add("wiseq");
proxy3.add("traits");
System.out.println("集合元素的個數="+proxy3.size());
//Proxy也是肯定繼承自Object ,
//proxy3.getClass()為啥不調用目標類的getClass()得到ArrayList的字節碼?
//那是因為Object只有三個方法委托給了InvocationHander, 分別是 toString 、hashCode 、 equals ,而getClass()方法,生成的代理類有自己的實現
System.out.println(proxy3.getClass().getName());
}
}

把切面的方法以對象的方式封裝,把對象傳遞給代理對象,代理對象執行傳入的對象方法 就等於執行了切面的代碼
想上面我們看到的硬編碼方式的動態代理在實際的開發中是沒有任何意義的,要變的更有用,需要將一些東西抽出去,實現參數化 代理
