java动态代理
来源:互联网 发布:java 策略模式应用 编辑:程序博客网 时间:2024/05/20 23:37
1. 动态代理是什么?
代理:A需要访问C,但是A又不能或不想直接访问C,如果说A可以通过B来访问C,此时B就是C的代理。在java中,B需要实现和C一样的接口,这样B才能代理C完成任务,实际的任务的完成还是有C来完成。
静态代理:在编译时,代理类的.class文件就已经存在。
动态代理:在运行时,动态生成代理类。很显然动态代理的实现需要用到java的反射机制。
2.为什么要使用动态代理?
相对于不使用代理的情况,使用代理可以在调用被代理类的方法时,添加其他操作,比如过滤消息、对消息预处理以及消息处理之后等操作。
相对于静态代理来说,静态代理在编译时,被代理类就必须存在,且每个代理对象中都会包含一个被代理对象,这样会导致类急剧膨胀。
3. 如何使用动态代理
动态代理的实现主要依赖于Proxy类和InvocationHandler接口。
Proxy类中的Static Object newProxyInstance(ClassLoader loader, Class[] intefaces, InvocationHandler h)函数会做:1.根据interfaces动态生成代理类proxy.$Proxy0 2.生成一个proxy.$Proxy0的对象并返回给调用者 3.调用者调用proxy.$Proxy0中的方法时,最终会通过调用h中的invoke()函数来调用被代理类的方法。
InvocationHandler接口通常会被代理类继承,接口实例会被传入到newProxyInstance()方法,动态代理类的对象最终会通过InvocationHandler中的invoke()函数来调用被代理的对象,使用的是java反射机制。
Subject.java:
package com.zhb.dynamicproxy;public interface Subject {void request();}
AnotherSubject.java:
package com.zhb.dynamicproxy;public interface AnotherSubject {public String Hello(String a);}
DynamicSubject.java:
package com.zhb.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;//需要实现InvocationHandler接口public class DynamicSubject implements InvocationHandler {private Object sub;public DynamicSubject(Object o){this.sub = o;//将真实角色的对象保存到sub中}public Object invoke(Object arg0, Method arg1, Object[] arg2)throws Throwable {Object o = null;System.out.println("before invoke:"+arg1.toString());o = arg1.invoke(sub, arg2);//通过反射调用真实角色sub的方法System.out.println("after invoke:"+arg1.toString());return o;}}
Client.java:
package com.zhb.dynamicproxy;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Client {public static void main(String[] args) throws Exception {RealSubject realSubject = new RealSubject();// 创建真实角色的对象InvocationHandler invocationHandler = new DynamicSubject(realSubject);// 初始化代理角色Class cls = realSubject.getClass();Class<?> c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces());// 根据真实角色 构建、返回一个proxy类Constructor<?> ctor = c.getConstructor(new Class[] { InvocationHandler.class });Subject subject2 = (Subject) ctor.newInstance(new Object[] { invocationHandler });// 创建一个之前构建的proxy类的接口对象subject2.request();AnotherSubject subject3 = (AnotherSubject) ctor.newInstance(new Object[] { invocationHandler });System.out.println(subject3.Hello("world"));// Proxy.newProxyInstance等价于上述三个函数,运行时动态生成一个proxy.$Proxy0类,该类实现了真实角色的接口,并返回proxy.$Proxy0的一个对象//把需要调用的接口cls.getInterfaces(),以及代理角色invocationHandler告诉 Proxy.newProxyInstance,该函数就会根据你提供的接口动态生成一个proxy.$Proxy0类,//并返回该类的一个对象subject,对subject调用相应的方法时,会调用invocationHandler中的invoke()函数,通过反射来调用真实角色的方法。Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), invocationHandler);subject.request();System.out.println(subject.getClass());AnotherSubject subject4 = (AnotherSubject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), invocationHandler);System.out.println(subject4.getClass() + " " + subject4.Hello("zhb"));}}
运行结果:
before invoke:public abstract void com.zhb.dynamicproxy.Subject.request()
from realsubject
after invoke:public abstract void com.zhb.dynamicproxy.Subject.request()
before invoke:public abstract java.lang.String com.zhb.dynamicproxy.AnotherSubject.Hello(java.lang.String)
after invoke:public abstract java.lang.String com.zhb.dynamicproxy.AnotherSubject.Hello(java.lang.String)
hello world
before invoke:public abstract void com.zhb.dynamicproxy.Subject.request()
from realsubject
after invoke:public abstract void com.zhb.dynamicproxy.Subject.request()
class com.sun.proxy.$Proxy0
before invoke:public abstract java.lang.String com.zhb.dynamicproxy.AnotherSubject.Hello(java.lang.String)
after invoke:public abstract java.lang.String com.zhb.dynamicproxy.AnotherSubject.Hello(java.lang.String)
class com.sun.proxy.$Proxy0 hello zhb
- Java 代理,动态代理
- [Java] Java 动态代理
- java代理及动态代理
- java代理模式--动态代理
- Java静态代理、动态代理
- Java 代理之 动态代理
- Java 代理与动态代理
- java静态代理,动态代理
- 代理模式&java动态代理
- Java代理与动态代理
- Java静态代理动态代理
- JAVA代理模式--动态代理
- java 代理和动态代理
- JAVA动态代理 代理模式
- Java动态代理--jdk代理
- Java动态代理--cglib代理
- Java 代理与动态代理
- java代理模式-动态代理
- nyoj195&&nyoj201(递增递减dp)
- 给重回正路的大二学生:戒急戒躁中前行
- leetcode day4 -- Binary Tree Postorder(Preorder) Traversal && Edit Distance
- 对网页游戏《卧龙吟》的分析3-----预登陆flash的源代码分析
- 引用内部类
- java动态代理
- C++中的单例模式
- error C2665: “outtextxy”: 2 个重载中没有一个可以转换所有参数类型
- 特征向量的几何意义
- Quartz 框架 教程(中文版)2.2.x 之第三课 更多关于Jobs和JobDetails
- Fedora启动自动获得IP
- bash使用快捷键
- hibernate中另外两种配置文件方式的配置
- opencv中的Mat类型的相关概念