黑马程序员--加强之动态代理

-------android培训java培训、期待与您交流!     ---------- 

package cn.itcast.day3;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class ProxyTest
{

	public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException
	{
		Class clazzProxy1 =
			Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);//接口的Class对象
		System.out.println(clazzProxy1.getName()); //com.sun.proxy.$Proxy0
		
		System.out.println("-----------begin constructor list -------------");
		/*
		 * list the constructors in the form of $Proxy0() or $Proxy(InvocationHadler h)
		 * */
		Constructor[] constructors = clazzProxy1.getConstructors();
		for(Constructor constructor : constructors)
		{	
			String name = constructor.getName();
			StringBuilder sBuilder = new StringBuilder(name);
			sBuilder.append("(");
			Class[] clazzParams = constructor.getParameterTypes();
			for(Class clazzParm : clazzParams)
			{
				sBuilder.append(clazzParm.getName()).append(",");
			}
			if(clazzParams!=null && clazzParams.length!=0)
			{
				sBuilder.deleteCharAt(sBuilder.length()-1);
			}
			sBuilder.append(")");
			System.out.println(sBuilder.toString());
			//com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler)
		}
		
		System.out.println("--------------------begin methods list ----------------");
		Method[] methods = clazzProxy1.getMethods();
		for(Method method : methods)
		{
			String name = method.getName();
			StringBuilder sBuilder = new StringBuilder(name);
			Class[] clazzParamTypes = method.getParameterTypes();
			sBuilder.append("(");
			for(Class clazzParamType : clazzParamTypes)
			{
				sBuilder.append(clazzParamType.getName()).append(",");
			}
			if(0 != clazzParamTypes.length)
			{
				sBuilder.deleteCharAt(sBuilder.length()-1);
			}
			sBuilder.append(")");
			System.out.println(sBuilder.toString());
			//newProxyInstance(java.lang.ClassLoader,[Ljava.lang.Class;,java.lang.reflect.InvocationHandler)
		}
		
		System.out.println("-------------begin create instance object---------------");
		Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);
		Collection proxy1 = (Collection) constructor.newInstance(new InvocationHandler()//转化为接口,即父类.向上转型
		{
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable
			{
				// TODO Auto-generated method stub
				return 10;//要与接口中的返回值一致,应返回接口的方法调用,作用于target对象
			}
		});
		//System.out.println(proxy1);
		proxy1.clear(); //no return value, no error!;
		proxy1.size(); // return int, null pointer exception
		
		System.out.println("-------------target appear-------------");
		final ArrayList target = new ArrayList();//要实现Collection接口,与proxy1一样
		Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler()
		{
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable
			{	
				//System.out.println(proxy);//??????
				System.out.println("before invoke target method.");//可封装为对象的方法
				Object retVal = method.invoke(target, args);//返回目标对象的方法调用 .此时内存中有两个此方法对象的拥用者:proxy,target
				System.out.println("after invoke target method.");
				
				return retVal;
			}
		});
		proxy2.clear();
		System.out.println(proxy2);
		proxy2.add('a');
		proxy2.add('b');
		System.out.println(proxy2.size());
		System.out.println(proxy2.getClass().getName());
		
		System.out.println("----------------封装advice方法---------------");
		Collection proxy3 = getProxy(target, new MyAdvice());
		proxy3.add("3");
		proxy3.add("4");
		proxy3.add("5");
		System.out.println(proxy3.size());
		System.out.println(proxy3.getClass().getName());
	}

	private static Collection getProxy(final ArrayList target, final Advice advice)
	{
		final Object collection = 
			Proxy.newProxyInstance(Collection.class.getClassLoader(), 
					new Class[]{Collection.class}, //必须是数组,不是可变参数形式,区别于getProxyClass();
					new InvocationHandler()
					{	
						int i = 0;
						@Override
						public Object invoke(Object proxy, Method method, Object[] args)
								throws Throwable
						{	
							advice.beforeMethod(method);
							Object retVal = method.invoke(target, args);
							advice.afterMethod(method);
							if(i++ < 1)
								System.out.println("proxy:"+proxy.hashCode());//所有对proxy对象的方法调用,都会转到这里执行;proxy对象就是要返回的对象
							else
								return retVal;
							return retVal;
						}
					});
		System.out.println("collection:"+collection.hashCode());
		return (Collection)collection;
	}

}
package cn.itcast.day3;

import java.lang.reflect.Method;

public interface Advice
{
	void beforeMethod(Method method);
	void afterMethod(Method method);
}
package cn.itcast.day3;

import java.lang.reflect.Method;

public class MyAdvice implements Advice
{
	private long start;
	
	@Override
	public void beforeMethod(Method method)
	{
		System.out.println("timing start...");
		start = System.currentTimeMillis();
	}

	@Override
	public void afterMethod(Method method)
	{
		System.out.println(method.getName()+" cost time:"+(System.currentTimeMillis()-start));
	}

}
------- android培训 java培训 、期待与您交流!     ----------  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值