我的设计模式学习之路3(动态代理)
2013-05-05 22:21
609 查看
代理模式(Proxy)
1.静态代理
角色:
抽象主题角色:声明了代理角色和真实角色的共同接口
代理角色:代理角色内部含有对真实角色的引用,通常在将客户端调整用传弟它们真实角色之前或者之后,都要执行某个操作
真实角色:定了代理角色所代表的真实对象
类图:
下面是我的写的一个例子:
首先是抽象主题角色:
package com.design.proxy; public interface Runable { public void move(); }代理角色,这里有两个:
package com.design.proxy; public class TankTimeProxy implements Runable { private Runable t; public TankTimeProxy(Runable t) { this.t=t; } @Override public void move() { System.out.println("time is start ........"); t.move(); } }
package com.design.proxy; public class TankLogProxy implements Runable { private Runable t; public TankLogProxy(Runable t) { this.t=t; } @Override public void move() { System.out.println("Log is record"); t.move(); } }
真实角色:
public class Tank implements Runable { @Override public void move() { long start=System.currentTimeMillis(); System.out.println("tank is move.."); try { Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) { e.printStackTrace(); } long end=System.currentTimeMillis(); System.out.println("time:"+(end-start)); } }
最后是测试类:
package com.design.proxy; public class Client { public static void main(String[] args) { Tank tank = new Tank(); TankTimeProxy ttp=new TankTimeProxy(tank); TankLogProxy tlp = new TankLogProxy(ttp); tlp.move(); } }
输出结果:
Log is record
time is start ........
tank is move..
time:1728
测试类可以动态地改变,相应由不同的代理角色来完成不同的功能,这是简单的代理,缺点就是不太灵活。
2.动态代理
动态代理需要实现InvocationHandler这个接口,并且@Ovrride里面的invoke()方法,让InvocationHandler接口来帮我们代理,代理类需要有个静态工厂的方法,下面是我的一个例子:
接口:
package com.proxy2; public interface UserManager { public void save(); }
接口的实现:
package com.proxy2; public class UserManagerImpl implements UserManager { @Override public void save() { System.out.println("用户保存中..."); } }两个代理类:
package com.proxy2; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class UserLogProxy implements InvocationHandler { private Object target; public UserLogProxy(Object target) { this.target=target; } public static Object factory(Object obj) { Class<?> clazz= obj.getClass(); return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new UserLogProxy(obj)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开始写日记..."); Object o=method.invoke(target, args); System.out.println("记录完毕...."); return o; } }
package com.proxy2; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class UserInvokedProxy implements InvocationHandler { private Object target; public UserInvokedProxy(Object target) { this.target=target; } public static Object factory(Object obj) { Class<?> clazz= obj.getClass(); return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new UserInvokedProxy(obj)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("类加载..."); Object o=method.invoke(target, args); return o; } }
测试类:
package com.proxy2; public class Client { public static void main(String[] args) { UserManager user = new UserManagerImpl(); UserManager user1=(UserManager)UserLogProxy.factory(user); UserManager user2=(UserManager)UserInvokedProxy.factory(user1); user2.save(); } }
测试的结果:
类加载中...
开始写日记...
用户保存中...
记录完毕....
这样就可以实现了动态代理,而且是一个对象对应多个代理。动态代理的应用还是很广泛的,比如Spring的AOP等,感谢《JAVA与设计模式》这本书,让我知道了多个代理的写法。
相关文章推荐
- java学习之路---设计模式---动态代理
- java学习之路---设计模式----工厂代理模式的进一步研究
- 设计模式之代理模式学习------动态代理-----《设计模式之禅》学习笔记
- Java-马士兵设计模式学习笔记-代理模式--动态代理 修改成可以代理任意接口
- 学习:java设计模式—动态代理模式
- 设计模式学习——动态代理实现C#动态调用WebService(附源码)
- 学习:java设计模式—动态代理模式
- Java-马士兵设计模式学习笔记-代理模式-动态代理 调用Proxy.newProxyInstance()
- Java设计模式学习06——静态代理与动态代理
- 设计模式学习笔记(三)动态代理模式
- 设计模式学习之路 - 装饰者模式 - 动态扩展器
- Java-马士兵设计模式学习笔记-代理模式-动态代理 修改成可以任意修改代理逻辑
- Java设计模式学习06——静态代理与动态代理
- 设计模式学习之代理模式(二)--CGLIB实现对Class动态代理
- 设计模式学习之动态代理模式
- 设计模式学习之路-代理模式
- java学习之路之接口(4)--代理设计模式(代码)
- 15. JAVA 反射机制 Part 2(动态代理、类的生命周期、工厂设计模式) ----- 学习笔记
- java学习之路--设计模式---代理模式
- 设计模式的学习之路--模板方法设计模式