黑马程序员——静态代理与动态代理
来源:互联网 发布:二手警服淘宝 编辑:程序博客网 时间:2024/05/16 01:50
一、什么是代理
Java的代理模式在生活是非常常见的,比如一个人去租房子,可以去找房屋中介,也可以去找房子的主人,最终的目的是租到房子。两种方式都可以解决问题,中介就相当于一个代理,找它解决可能会更省时省力。在Java编程中使用代理模式,目的就是为其他对象提供一个代理以控制对某个对象的访问。代理模式涉及到三个角色:
(1)抽象角色:声明真实角色的接口。
(2)真实角色:抽象角色的实现。
(3)代理角色:代理角色内可以含有对真实角色的引用,同时可以实现一些附加操作。
二、静态代理
静态代理就是简单的将真实角色中的方法重新实现,重载抽象类中声明的方法。
抽象角色:
public interface subject {public void request();}
真实角色:public class realsubject implements subject {@Overridepublic void request() {System.out.println("From real subject!");}}
代理角色:public class proxysubject implements subject {@Overridepublic void request() {new realsubject().request();System.out.println("This is proxy!");}}
测试文件:public class proxyClient {public static void main(String[] args) {subject sub=new proxysubject();sub.request();}}
运行结果:
From real subject!
This is proxy!
从运行结果中可以看到,执行了真实角色的方法之后,又执行了自己的部分,就是打印“This is proxy”。这就相当于房屋中介在帮你在找到房子之后,会收取中间费用一样。静态代理缺点明显,代理角色和真实角色一一对应,这样对每一个类,都要有一个代理类与之对应,这样代码的复用率就下降,而动态代理可以很好的解决这一问题。
三、动态代理
Java动态代理机制的出现,使的Java开发人员不用手工编写代理类,只要简单的指定一组接口及委托类对象,便能动态的获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。Java动态代理具体有如下四个步骤:
(1)通过实现InvocationHandler接口创建自己的调用处理器。(2)通过为Proxy类指定ClassLoader对象和一组Interface来创建动态代理类。
(3)通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型。
(4)通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
抽象角色:
public interface Subject {public void show();}真实角色:
public class RealSubject implements Subject {public void show() {System.out.println("From Real Subject");}}代理角色:
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;//实现 InvocationHandler接口创建自己的调用处理器public class ProxySubject implements InvocationHandler {private Object sub;public ProxySubject(Object obj){sub=obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("before calling:"+method);method.invoke(sub, args);System.out.println("after calling:"+method);return null;}}
测试文件:import java.lang.reflect.*;public class Client {public static void main(String[] args) {RealSubject realsub=new RealSubject();InvocationHandler handler=new ProxySubject(realsub);Class<?> classType=handler.getClass();//newProxyInstance()用于为指定类加载器、一组接口及调用处理器生成动态代理类实例Subject sub=(Subject)Proxy.newProxyInstance(classType.getClassLoader(),RealSubject.class.getInterfaces(),handler);sub.show();}}
执行结果:before calling:public abstract void dynamicproxy.Subject.show()
From Real Subject
after calling:public abstract void dynamicproxy.Subject.show()
执行的过程是这样的:
sub.show()------>handler.Invoke()------>realsub.show()
再回头来看动态代理,用的是最基本的Object类,根本就没有与Subject类绑定,因此它可以作为所有从Object衍生出的子类的代理,即一对多的代理,极大的提高了代码的复用率。上面的这种动态代理叫做jdk proxy即原生的jdk代理,它其实不是完美的,只能代理实现了接口的类,要想完成对类本身实现代理,就需要用到另外一个开源的类库cglib。
- 黑马程序员——静态代理与动态代理
- 黑马程序员—代理与动态代理
- 黑马程序员--静态代理和动态代理
- 黑马程序员--静态代理和动态代理
- 黑马程序员—动态代理
- 黑马程序员:Java基础总结----静态代理模式&动态代理
- 黑马程序员 jdk的静态代理和动态代理
- 黑马程序员_动态代理和静态代理总结
- 黑马程序员——Java动态代理
- 黑马程序员——动态代理技术
- 黑马程序员——动态代理类
- 黑马程序员——动态代理
- 黑马程序员——动态代理技术
- 黑马程序员——动态代理
- 黑马程序员——动态代理
- 黑马程序员——动态代理详解
- 黑马程序员—动态代理模式
- 黑马程序员—高新技术:动态代理
- SQLPLUS中应用参数查询
- poj 1017 packets 装箱问题
- HTML学习笔记(七)
- OpenGL 超级宝典学习,制作 圆柱,球体,花托,圆盘等多边体
- leetcode Palindrome Partitioning
- 黑马程序员——静态代理与动态代理
- 经典玩笑
- 机器学习进阶之贝叶斯
- Codeforces Round #277 (Div. 2)(D)
- Android开发之画笔
- 央视2014“杰出工程师奖”颁奖典礼将播出 致敬工程师
- 让爱继续
- leetcode Letter Combinations of a Phone Number
- 一篇写的很好的程序员职业规划,收藏起来!