程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> jdk動態代理,jdk動態

jdk動態代理,jdk動態

編輯:JAVA綜合教程

jdk動態代理,jdk動態


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());
	
		
	}

}

 

把切面的方法以對象的方式封裝,把對象傳遞給代理對象,代理對象執行傳入的對象方法 就等於執行了切面的代碼

 

 

想上面我們看到的硬編碼方式的動態代理在實際的開發中是沒有任何意義的,要變的更有用,需要將一些東西抽出去,實現參數化 代理

 

image

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved