黑马程序员_代理

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
 

 

一、代理作用

        要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,在不对元程序进行修改的情况下,可以采用代理来完成。
        通过编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。
       代理结构图
二、代理创建方式
        要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情,因此实际开发过程中存在两种建立代理的方式
       1,JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
        此种创建代理的方式要求目标类要实现接口
        2,CGLIB库
        CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
        这种方式可以对没有实现接口的目标类进行代理的创建
        3,代理类系统功能代码存放的位置
              3.1,在调用目标方法之前
              3.2,在调用目标方法之后
              3.3,在调用目标方法前后
              3.4,在处理目标方法异常的catch块中
三、创建动态代理类
       利用Proxy类的静态方法getProxyClass方法的到proxy类的class实例。
import java.lang.reflect.Proxy;
import java.util.Collection;

public class ProxyTest2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Class clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		System.out.println(clazzProxy.getName());

	}

}
       获取Proxy类的构造函数及参数
import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.Collection;

public class ProxyTest2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Class clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		System.out.println(clazzProxy.getName());
		//获取Proxy的构造函数
		Constructor[] constructors = clazzProxy.getConstructors();
		System.out.println(constructors.length);
		Constructor proxyConstructor = constructors[0];
		//获取构造函数的参数列表
		Class[] clazzParameterTypes = proxyConstructor.getParameterTypes();
		StringBuilder sb = new StringBuilder();
		sb.append(proxyConstructor.getName());
		for(Class clazzParameterType:clazzParameterTypes){
			sb.append("(");
			sb.append(clazzParameterType.getName());
			sb.append(")");
		}
		System.out.println(sb.toString());
	}

}

四、创建动态代理类的对象

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 ProxyTest2 {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws  
	 * @throws  
	 * @throws  
	 */
	public static void main(String[] args) throws Exception {
		Class clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		System.out.println(clazzProxy.getName());
		//获取Proxy的构造函数
		Constructor[] constructors = clazzProxy.getConstructors();
		System.out.println(constructors.length);
		Constructor proxyConstructor = constructors[0];
		//创建动态代理的对象
		Collection collection = (Collection)proxyConstructor.newInstance(new InvocationHandler() {
			ArrayList<String> al = new ArrayList<String>();
			Object retVal = null;
			@Override//复写invoke方法
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				retVal = method.invoke(al, args);
				return retVal;
			}
		});
		//调用代理类
		collection.add("1");
		collection.add("2");
		collection.add("3");
		System.out.println(collection.size());
		
	}

}

五、动态生成的类的内部代码分析


       动态类在调用方法时将三要素作为参数传递给了InvocationHandler对象,InvocationHandler对象调用自己的invoke方法,并在内部调用目标类的方法,并且在内部还可以增加系统功能方法。

       动态代理的工作原理图

 

          在实际应用中将创建代理类封装成一个方法,并将系统的功能代码封装进对象,作为参数传递进去,通过调用这个对象的方法来完成系统的功能代码块。

 

 

 

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------详细请查看:<a href="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>


 

 

 

 




 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值