动态代理

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

为已经写好的类增加功能

客户端程序不在直接调用目标类,而是调用代理类,代理类在代码里面调用目标类,在加上额外的增强功能,代理类和目标类要实现相同的接口

1、  AOP切面编程

系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面,交叉业务的编程问题即为面向方面的编程,AOP的目标就是要使交叉业务模块化

2、  动态代理

JVM生成的动态类必须实现一个或多个接口

让JVM创建动态类需要提供的信息:生成的类中有哪些方法,通过让其实现那些接口的方式进行告知、产生的类字节码必须有一个关联的类加载器对象、生成的类中的方法的代码是怎样的,也得有我们提供,把我们的代码写在一个约定好的接口对象方法中,把对象传给它,它调用我的方法,即相当于插入了我的代码。提供执行代码的对象就是那个InvocationHandler对象,它是在创建动态类的实例对象的构造方法时传递进去的。

注:只有tostring,hashCold,equlse这三个方法委托为handler其它的不委托

/**
 *获得一个动态类 并实例化对象 
 * @author Administrator
 *
 */
public class ProctCollection {

	public static void main(String[] args) throws Exception{
		
		
		//得到构造函数
		
		//第一个参数表示用什么类加载器,第二而参数是实现接口
		Class Clazzproxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		Constructor[] constructors = Clazzproxy1.getConstructors();
		for (Constructor constructor : constructors) {
			//单线程的时候用StringBuilder多线程的时候用StringBuffer
			//StringBuffer考虑线程安全问题,效率不高,Stringbuilder不考虑线程安全
			StringBuilder builder = new StringBuilder();
			String name = constructor.getName();
			builder.append(name);
			builder.append('(');
			Type[] types = constructor.getGenericParameterTypes();
			for (Type type : types) {
				builder.append(type);
				builder.append(',');
			}
			if (types!=null&&types.length!=0) {
				builder.deleteCharAt(builder.lastIndexOf(","));
			}
			builder.append(')');
			System.out.println(builder.toString());
		}
		
		
		//对象发发
		
		Method[] methods = Clazzproxy1.getMethods();
		for (Method method : methods) {
			//单线程的时候用StringBuilder多线程的时候用StringBuffer
			//StringBuffer考虑线程安全问题,效率不高,Stringbuilder不考虑线程安全
			StringBuilder builder = new StringBuilder();
			String name = method.getName();
			builder.append(name);
			builder.append('(');
			Type[] types = method.getGenericParameterTypes();
			for (Type type : types) {
				builder.append(type);
				builder.append(',');
			}
			if (types!=null&&types.length!=0) {
				builder.deleteCharAt(builder.lastIndexOf(","));
			}
			builder.append(')');
			System.out.println(builder.toString());
		}
		
		
		//实例化对象
		class MyInvocationHandler implements InvocationHandler {

			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				return null;
			}
			
		}
		Collection proxy1 = (Collection) Clazzproxy1.getConstructor(InvocationHandler.class).newInstance(new MyInvocationHandler());
		
		Collection proxy2 = (Collection) Clazzproxy1.getConstructor(InvocationHandler.class).newInstance(new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				
				return null;
			}
		});
		
		Collection proxy3 = (Collection) Proxy.newProxyInstance(
				Collection.class.getClassLoader(), 
				new Class[]{Collection.class}, 
				new InvocationHandler() {
					//三个参数分别表示,调用的是哪个代理,代理的方法,方法的参数 proxy3.add("asd");
					ArrayList aList = new ArrayList();
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						//代理增加功能
						long starTime = System.currentTimeMillis();
						//目标返回结果
						Object relVal = method.invoke(aList, args);
						//代理增加功能
						long endTime = System.currentTimeMillis();
						System.out.println(endTime-starTime);
						return relVal;
					}
				});
		proxy3.add("asd");
		proxy3.add("qwe");
		proxy3.add("zxc");
		System.out.println(proxy3.size());
		
	}

}


---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值