通过java反射让JVM自动的创建动态代理类

本文介绍了一个Java动态代理的实现案例,展示了如何利用Java反射API创建动态代理对象,并通过具体示例说明了代理对象的构造、方法调用及其实现机制。
import java.lang.annotation.Target;
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;

/**
 * @author Dqd
 *ClassLoader loader 
----指定被代理对象的类加载器
Class[] Interfaces 
----指定被代理对象所实现的接口
InvocationHandler h ----指定需要调用的InvocationHandler对象
 *
 */

public class ProxyTest {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		Class classProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		System.out.println(classProxy1.getName());
		System.out.println("构造参数列表为");
		Constructor[] con = classProxy1.getConstructors();
		for(Constructor co : con){
			String str = co.getName();
			StringBuilder sb = new StringBuilder(str);
			sb.append("(");
			Class[] para = co.getParameterTypes();
			for(Class pa:para){
				sb.append(pa.getName()).append(',');
			}
			if(para!=null && para.length!=0){
				sb.deleteCharAt(sb.length()-1);
			}
			sb.append(")");
			System.out.println(sb.toString());	
		}
		
		
		System.out.println("方法列表为");
		Method[] con1 = classProxy1.getMethods();
		for(Method co : con1){
			String str = co.getName();
			StringBuilder sb = new StringBuilder(str);
			sb.append("(");
			Class[] para = co.getParameterTypes();
			for(Class pa:para){
				sb.append(pa.getName()).append(',');
			}
			if(para!=null && para.length!=0){
				sb.deleteCharAt(sb.length()-1);
			}
			sb.append(")");
			System.out.println(sb.toString());	
		}
		
		System.out.println("创建对象实例");
		//因为代理对象的构造函数没有无参的所以下面代码运行会有异常
		//Object obj = (Object)classProxy1.newInstance();
		
		Constructor constructor = classProxy1.getConstructor(InvocationHandler.class);
		//其中的InvocationHandler是一个接口所以要通过子类去实现
		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());
		//注意如果直接输出proxy1代理对象创建的实现会输出null,但是这里的null可能是proxy1对象创建的有问题本身就是nul
		//另一种情况就是对象的toString()返回的是一个null
		System.out.println(proxy1.toString()+"通过有构造参数创建的");
		proxy1.clear();
		//如果调用下面有返回值的函数就会报错
		//proxy1.size();
		
		
		
		//由于proxy1使用内部类进行生成的只用了一次
		//所以我们可以直接的new Interface(){}(既匿名内部类)
		Collection proxy2 =(Collection) constructor.newInstance(new InvocationHandler(){

			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return null;
			}
		});
		
		
		
		
		
		
		
		
		
		//将目标(既ArrayList)抽取成为一个对象
		System.out.println("-------开始运行代理类------");
		final ArrayList al = new ArrayList();
		//方Myadvice是系统功能,和过程代码分离,灵活了AOP
		Collection proxy3 = (Collection)getProxy(al,new MyAdvice());
		proxy3.add("zxc");
		proxy3.add("345");
		System.out.println(proxy3.size());		
	}

	private static Object getProxy(final Object target,final Advice advice) {
		Object proxy3 = (Object)Proxy.newProxyInstance(
				target.getClass().getClassLoader(),
				//new Class[]{Collection.class},
				target.getClass().getInterfaces(),
				new InvocationHandler() {
					//分别是对象,方法,参数
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
/*						long bt = System.currentTimeMillis();
						//将调用的方法关联起来
						Object retVal = method.invoke(target, args);
						for (int i = 0; i <10; i++) {
						}
						long et = System.currentTimeMillis();
						System.out.println(method.getName()+" "+ (et - bt )+"hehe");
						return retVal;*/
						
						
						//直接调用方法
						advice.beforeMethod(method);
						//将调用的方法关联起来
						Object retVal = method.invoke(target, args);
						for (int i = 0; i <10; i++) {
						}
						advice.afterMethod(method);
						return retVal;
					}
				}
		);
		return proxy3;
	}
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值