java類載入器和動態代理
阿新 • • 發佈:2019-02-16
import java.lang.reflect.*; import java.util.ArrayList; import java.util.Collection; public class ProxyTest { public static void main(String[] args) throws Exception { //Proxy的靜態方法getProxyClass獲取動態代理Class物件 Class clazzProxy1=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); System.out.println(clazzProxy1.getName()); //列出動態代理類的所有構造方法和引數簽名 System.out.println(".....begin constructors list....."); Constructor[] constructors=clazzProxy1.getConstructors(); for(Constructor constructor:constructors){ String name=constructor.getName(); StringBuilder sbu=new StringBuilder(name); sbu.append("("); Class[] clazzParams=constructor.getParameterTypes(); for(Class clazzParam:clazzParams){ sbu.append(clazzParam.getName()).append(","); } if(clazzParams!=null&&clazzParams.length!=0){ sbu.deleteCharAt(sbu.length()-1); } sbu.append(")"); System.out.println(sbu.toString()); } //列出動態代理類的所有方法和引數簽名 System.out.println(".....begin Methods list....."); Method[] methods=clazzProxy1.getMethods(); for(Method method:methods){ String name=method.getName(); StringBuilder sbu=new StringBuilder(name); sbu.append("("); Class[] clazzParams=method.getParameterTypes(); for(Class clazzParam:clazzParams){ sbu.append(clazzParam.getName()).append(","); } if(clazzParams!=null&&clazzParams.length!=0){ sbu.deleteCharAt(sbu.length()-1); } sbu.append(")"); System.out.println(sbu.toString()); } //建立動態代理類的例項物件 //方式一: System.out.println(".....begin create instance object....."); Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class); class MyInvocationHandler1 implements InvocationHandler{ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub return null; } } Collection proxy1=(Collection)constructor.newInstance(new MyInvocationHandler1()); //代理類中從java.lang.Object類繼承的方法中,只有hashCode(),equals()和toString()方法會委託給Invocationhandler執行,執行時會執行InvocationHandler中的invoke()方法,其它從Object類中繼承的方法不會委託給Invocationhandle. System.out.println(proxy1); //沒有返回值的clear()方法可正常執行,因為InvocationHandler返回null,與clear()原先的返回型別void不矛盾。 proxy1.clear(); //執行時報錯,因為size()應該返回整數值,但現在委託給InvocationHandler後返回的是null,不匹配 //System.out.println(proxy1.size()); //方式二:匿名內部類方式 Collection proxy2=(Collection)constructor.newInstance(new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } }); //方式三:直接使用Proxy的靜態方法newProxyInstance()方法 Collection proxy3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler(){ //建立目標類例項物件 ArrayList target=new ArrayList(); public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //在目標類的基礎功能前進行功能擴充套件 long beginTime=System.currentTimeMillis(); //執行目標物件的method方法 Object retVal=method.invoke(target, args); //在目標類的基礎功能後進行功能擴充套件 long endTime=System.currentTimeMillis(); System.out.println(method.getName()+" running time of "+(endTime-beginTime)); return retVal; } } ); //每次呼叫proxy3的add方法,其實都是執行InvocationHandler子類中的invoke()方法,將proxy3賦給invoke()方法的第一個引數,add代表的Method物件賦經第從此引數,add()的引數"sss"賦給invoke()的第3個引數args proxy3.add("sss"); proxy3.add("wtet"); Object retVal=(Object)proxy3.add("gfdh"); System.out.println(retVal); System.out.println(proxy3.size()); //動態代理類的getClass()方法不會委託給InvocationHandler執行,所以仍列印是的$Proxy0,而不是ArrayList System.out.println(proxy3.getClass().getName()); } } /*執行結果: com.sun.proxy.$Proxy0 .....begin constructors list..... com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler) .....begin Methods list..... add(java.lang.Object) remove(java.lang.Object) equals(java.lang.Object) toString() hashCode() clear() contains(java.lang.Object) isEmpty() size() toArray() toArray([Ljava.lang.Object;) addAll(java.util.Collection) iterator() containsAll(java.util.Collection) removeAll(java.util.Collection) retainAll(java.util.Collection) isProxyClass(java.lang.Class) getInvocationHandler(java.lang.Object) getProxyClass(java.lang.ClassLoader,[Ljava.lang.Class;) newProxyInstance(java.lang.ClassLoader,[Ljava.lang.Class;,java.lang.reflect.InvocationHandler) wait(long,int) wait(long) wait() getClass() notify() notifyAll() .....begin create instance object..... null add running time of 1 add running time of 0 add running time of 0 true size running time of 0 3 com.sun.proxy.$Proxy0 */