Java 代理与动态代理
来源:互联网 发布:云计算专业就业前景 编辑:程序博客网 时间:2024/04/29 04:21
Java代理&动态代理
Java中得代理可以理解为中介,客户端和目标类的中介。
代理: 客户端--(通过)--代理类方法---(调用)---目标方法。
在代理类调用目标方法前后可以添加一些系统方法。
特点:代理类和目标类实现相同得接口。为什么?实现了相同接口,
那么代理类中得方法和目标内得方法相同,方便调用目标方法。
为什么要使用代理:
当把一个类做好后(或不知道这个类得具体代码),要为这个类添加新的系统功能
(如:异常处理,日志,计算方法运行得时间,等等),这个类已经封装好了,不想修改。
这时就可以创建一个和目标类实现相同接口得代理类,代理类中的方法与目标类中相同,
代理类中的方法引用目标类的方法。这时就可以在代理类方法,引用目标类方法,
前后添加系统功能。 达到调用代理类方法就能调用目标类方法,同时还能添加一些系统功能。
如:
接口 interface A { void show(); } 目标类:class Bimplements A{ publicvoidshow(){ System.out.println("吃饭"); }} 代理类:class Cimplements A{ publicvoid show(){ long bigTime = System.currentTimeMillis(); //前置系统代码。如: new B().show(); //后置系统代码。如: long endTime = System.currentTimeMillis(); System.out.println(endTime-bigTime); } } 可以在代理类引用目标类,前后添加新的功能。 动态代理: 为什么要有动态代理: 系统中有很多接口,接口下有很多类,如果要为每一个类写代理类,那就非常麻烦。 而java虚拟机可以在运行期动态生成字节码,可以把动态生成的字节码做为代理类。 这就是动态代理,解决了程序员不要直接写每个代理类的问题。想要java虚拟机自动生成动态代理, 需要想java虚拟机中传递两个参数, 一是,目标类的接口。二是:接口的类加载器。 自定义一个collection接口的代理类: (1) Class clazzproxy= Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);/*自动生成代理你得创建这个代理得对象。我们只有创建空参得方法,但自动生成代理得类中没有空参得构造方法 用反射得到有惨得构造方法*/ Constructorconstructor=clazzproxy.getConstructor(InvocationHandler.class);//在用constructor.newInstance实例化时,要向里面传递一个InvocationHandler对象。InvocationHandler是接口,不能new对象,所以,定义一个子类实现InvocationHandler接口,将子类对象传给constructor.newInstance(InvocationHandler子类对象)实例化。 class myInvocationHandlerimplementsInvocationHandler{ @Override public Object invoke(Objectarg0, Method arg1, Object[] arg2) throws Throwable { // TODO Auto-generated method stub returnnull; } } //实例化对象 Constructor proxy1 =(Constructor)constructor.newInstance(new myInvocationHandler()); (2) // 自动生成一个动态代理 //1.在内存中得到一个代理字节码,用到proxy类的getproxyclass方法 Class clazzproxy= Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class); //自动生成代理你得创建这个代理得对象。我们只有创建空参得方法,但自动生成代理得类中没有空参得构造方法 //用反射得到有惨得构造方法 Constructorconstructor=clazzproxy.getConstructor(InvocationHandler.class); Constructor proxy2 =(Constructor)constructor.newInstance(new InvocationHandler(){ @Override public Object invoke(Objectproxy, Method method, Object[]args) throwsThrowable { // TODO Auto-generated method stub returnnull; } }); (3) //我们用proxy类中newproxyInstance方法,该方法要传递3个参数。 (a):目标接口类加载器(b):目标接口数组(c):InvocationHandler对象。这样直接得到目标类的代理类。 这个方法将创建和实例化何为一体。 Collection proxy2 =(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[] {Collection.class}, new InvocationHandler(){ @Override public Object invoke(Object proxy, Methodmethod, Object[]args) throwsThrowable { // TODO Auto-generated method stub returnnull; } } ); } } 上面的类没有目标,可以在InvocationHandler对象中指定一个目标ArrayList。代码如下: Collection proxy2 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[] {Collection.class}, new InvocationHandler(){ @Override public Object invoke(Object proxy, Methodmethod, Object[]args) throws Throwable { ArrayList terget =new ArrayList(); *************************************** Object retval= method.invoke(terget,args);//调用目标的方法。 ******************************** return retval; } } ); }
}在**部分可以加入系统代码。上面的代码可以将method.invoke()方法和系统方法封装,作为参数传进去。
总结:
1.代理类就是一个中介,帮助目标类增加了一些功能,客服端调用代理方法,代理方法调用目标方法,这样代理类就可以在调用目标方法前后增加系统功能。
2.jvm生成的动态代理内部只有一个带InvocationHandler参数的构造方法。
3.代理类从object上继承的方法有很多,其中只对3个方法(hashcode equals tostring)进行开发,其他不会交给代理类实现。
4.静态代理:程序员自己编写而成的代理类源代码。
动态代理:在运行时jvm利用反射机制自动生成的代理类。
- Java 代理与动态代理
- Java代理与动态代理
- Java 代理与动态代理
- 代理模式与Java动态代理类
- java中的静态代理与动态代理
- 代理模式与Java动态代理类
- Java静态代理与动态代理
- java中的静态代理与动态代理
- Java静态代理与动态代理
- java中的静态代理与动态代理
- JAVA代理模式与动态代理模式
- JAVA代理模式与动态代理模式
- java静态代理与动态代理
- JAVA代理模式与动态代理模式
- Java 基础加强 - 代理与动态代理
- java的代理与动态代理
- Java动态代理与静态代理
- JAVA代理模式与动态代理模式
- hdu 2089 不要62 数位dp
- main函数参数分析 处理命令行选项
- JDK7最新特性
- stat函数的使用 获取文件状态 可以将文件状态复制保存在一个stat结构地址中,以此取得文件的大小等状态
- android.view.InflateException:Error inflating class fragment
- Java 代理与动态代理
- UVALive 5964 LCM Extreme(数论 欧拉函数)
- Command /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/
- C语言拓展——选择排序、冒泡排序、二分法查找
- Virtual Ethenet技术
- Java NIO系列教程(七) FileChannel
- line: 1: Syntax error: word unexpected (expecting ")")
- cv: 显示 cp、mv 等命令的进度
- lua实现面向对象