代理模式(静态代理、jdk动态代理)
2016-09-27 17:56
615 查看
1.代理模式的定义:
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
2.组成的角色:
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
3.代理模式的好处:
(1).职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介解耦的作用和保护了目标对象的作用,并可以附加自己的操作。
(3).高扩展性
4.通过小例子理解代理模式:
执行结果:
go home
这是一个最简单到代理模式的例子,客户端使用代理的dosomething()方法时,代理类委托给了真实角色ConcreteTarget执行,这就是代理模式。代理类成为客户端与真实角色直接的桥梁,在不同的场景下,这个桥梁可以起到很大的现实作用,这个在本文后面再讲述。
可以看到,该例中由于编译期已经知道代理的真实角色是谁了,所以这种代理模式又叫做静态代理。
5.jdk动态代理
相对静态代理而言,动态代理是值编译器不知道代理的真实角色是谁,需要在运行期才能确定。
我们有一个超级明星的接口。
有一个歌手实现了超级明星的接口。
但是明星都很忙的,还要耍耍大牌,所以需要一个经纪人作为他的代理人,处理对外事宜。可是现在是用的jdk动态代理了,与先前的例子写法完全不一样了。jdk API中有个InvocationHandler调用处理器的接口。我们需要先定义一个自己的调用处理器。
有了这2个类,代理就算完成了。
运行结果:
唱歌我在行,让我来
歌手同意了,我们准备准备就来
人不在,有什么事找我好了
跳舞别来找我们
true
jdk动态代理总结:
1.定义自己的InvocationHandler实现类BrokerInvocationHandler
2.通过Proxy类的newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)方法创建动态代理类
3.通过反射获取动态代理类的构造函数,并通过该构造函数创建代理类实例singer
4.被创建出来的实例singer继承了Proxy类(因此java动态代理只能代理接口,这是由java不支持多继承的设计决定的),实现了目标接口SuperStar
5.调用singer的任意方法,实际上都会先调用到BrokerInvocationHandler中的invoke方法,然后通过反射调用Method的invode方法调用实际被代理的方法
6.调用到BrokerInvocationHandler中的invoke方法时,可以获得被代理方法的信息,因此可以在真正调用invoke方法前、后写上自己的业务逻辑
5.代理模式的变形
在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用 Proxy模式。下面是一些可以使用Proxy模式常见情况:
1) 远程代理(Remote Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)
2) 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
3) 保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
4) 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
5) Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。
6)缓存代理(Cache Proxy)
7)防火墙代理(Application Gateway)
8)同步代理
等等。
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
2.组成的角色:
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
3.代理模式的好处:
(1).职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介解耦的作用和保护了目标对象的作用,并可以附加自己的操作。
(3).高扩展性
4.通过小例子理解代理模式:
public abstract class AbstractTarget { public abstract void dosomething(); }
public class ConcreteTarget extends AbstractTarget { @Override public void dosomething() { System.out.println("go home"); } }
public class MyProxy extends AbstractTarget { //静态代理 //编译期就已经明确指定了真实需要代理的类就是ConcreteTarget private AbstractTarget target = new ConcreteTarget(); @Override public void dosomething() { target.dosomething(); } }
public static void main(String[] args) { AbstractTarget target = new MyProxy(); target.dosomething(); }
执行结果:
go home
这是一个最简单到代理模式的例子,客户端使用代理的dosomething()方法时,代理类委托给了真实角色ConcreteTarget执行,这就是代理模式。代理类成为客户端与真实角色直接的桥梁,在不同的场景下,这个桥梁可以起到很大的现实作用,这个在本文后面再讲述。
可以看到,该例中由于编译期已经知道代理的真实角色是谁了,所以这种代理模式又叫做静态代理。
//静态代理 //编译期就已经明确指定了真实需要代理的类就是ConcreteTarget private AbstractTarget target = new ConcreteTarget();
5.jdk动态代理
相对静态代理而言,动态代理是值编译器不知道代理的真实角色是谁,需要在运行期才能确定。
我们有一个超级明星的接口。
public interface SuperStar { void call(); void sing(); void dance(); }
有一个歌手实现了超级明星的接口。
public class Singer implements SuperStar { @Override public void call() { System.out.println("我正在休息,不要打扰我"); } @Override public void sing() { System.out.println("唱歌我在行,让我来"); } @Override public void dance() { System.out.println("跳舞找dancer去"); } }
但是明星都很忙的,还要耍耍大牌,所以需要一个经纪人作为他的代理人,处理对外事宜。可是现在是用的jdk动态代理了,与先前的例子写法完全不一样了。jdk API中有个InvocationHandler调用处理器的接口。我们需要先定义一个自己的调用处理器。
public class BrokerInvocationHandler implements InvocationHandler { private SuperStar superStar; public BrokerInvocationHandler(SuperStar superStar){ this.superStar = superStar; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("sing")){ method.invoke(superStar,args); System.out.println("歌手同意了,我们准备准备就来"); return null; }else if (method.getName().equals("dance")){ System.out.println("跳舞别来找我们"); return null; }else if (method.getName().equals("call")){ System.out.println("人不在,有什么事找我好了"); return null; }else { return null; } } }
public class BrokerProxy { public static SuperStar newProxyInstance(SuperStar superStar){ return (SuperStar) Proxy.newProxyInstance(superStar.getClass().getClassLoader(), superStar.getClass().getInterfaces(),new BrokerInvocationHandler(superStar) ); } }
有了这2个类,代理就算完成了。
public class Test { public static void main(String[] args) { SuperStar singer = BrokerProxy.newProxyInstance(new Singer()); singer.sing(); singer.call(); singer.dance();
//true:说明singer的父类就是ProxySystem.out.println(singer.getClass().getSuperclass() == Proxy.class); }}
运行结果:
唱歌我在行,让我来
歌手同意了,我们准备准备就来
人不在,有什么事找我好了
跳舞别来找我们
true
jdk动态代理总结:
1.定义自己的InvocationHandler实现类BrokerInvocationHandler
2.通过Proxy类的newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)方法创建动态代理类
3.通过反射获取动态代理类的构造函数,并通过该构造函数创建代理类实例singer
4.被创建出来的实例singer继承了Proxy类(因此java动态代理只能代理接口,这是由java不支持多继承的设计决定的),实现了目标接口SuperStar
5.调用singer的任意方法,实际上都会先调用到BrokerInvocationHandler中的invoke方法,然后通过反射调用Method的invode方法调用实际被代理的方法
6.调用到BrokerInvocationHandler中的invoke方法时,可以获得被代理方法的信息,因此可以在真正调用invoke方法前、后写上自己的业务逻辑
5.代理模式的变形
在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用 Proxy模式。下面是一些可以使用Proxy模式常见情况:
1) 远程代理(Remote Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)
2) 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
3) 保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
4) 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
5) Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。
6)缓存代理(Cache Proxy)
7)防火墙代理(Application Gateway)
8)同步代理
等等。
相关文章推荐
- Java 代理模式:静态代理、JDK 动态代理和 Cglib 动态代理的区别
- 代理设计模式(普通静态代理、JDK动态代理、cglib动态代理)
- JAVA的代理模式(静态代理、JDK动态代理、cglib动态代理)
- 深入理解代理模式:静态代理与JDK动态代理
- 设计模式之代理模式(静态代理、JDK动态代理和cglib动态代理)
- 设计模式——代理模式(静态代理和JDK、CGLib动态代理)
- 黑马程序员:Java基础总结----静态代理模式&动态代理
- java代理(静态代理、动态代理)(JDK和cglib)
- 关于java中jdk中接口动态代理模式Proxy的剖析
- JDK静态代理及动态代理
- 架构设计之设计模式 (二) 静态代理和动态代理--间接“美”
- java代理设计模式(静态代理与动态代理)
- 代理模式proxy (静态代理、动态代理)
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- 静态代理模式、动态代理模式(实现、对比)
- 代理模式(静态代理+动态代理)——JAVA
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
- java 设计模式之四-代理模式 java静态代理和动态代理
- 静态代理和动态模式
- java 代理模式(静态代理+动态代理)