设计模式之代理模式
来源:互联网 发布:网络利弊议论文 编辑:程序博客网 时间:2024/06/08 19:22
设计模式之代理模式
代理模式(Proxy) 为其他对象提供一个代理以控制对这个对象的访问。
代理模式实现又分静态代理和动态代理。
结构图
代码示例
静态代理
需求:某一天,我和朋友老王聚会时,看见他的朋友娇妹很漂亮,想追求她。但是我又不好意思直接和娇妹打招呼,就想通过老王进行介绍认识。
实现时目标类和代理类实现同一个接口即可。
首先,定义打招呼的接口
public interface IMeetGirl {String sayHello();String doMyGirlFriend();}
真实的请求对象我:
public class Me implements IMeetGirl {private BeautifulGirl girl;public Me(BeautifulGirl girl) { this.girl = girl;}//定义真实的行为@Overridepublic String sayHello() { return girl.getName()+" 你好,我是一个大帅比!";}@Overridepublic String doMyGirlFriend() { return girl.getName()+" 做我女朋友吧!";}}
代理对象老王:
public class LaoWang implements IMeetGirl {private Me me;public LaoWang(BeautifulGirl girl) { me = new Me(girl);}//在代理方法中调用真实的方法@Overridepublic String sayHello() { return me.sayHello();}@Overridepublic String doMyGirlFriend() { return me.doMyGirlFriend();}}
实体类
public class BeautifulGirl {private String name;public String getName() { return name;}public void setName(String name) { this.name = name;}}
public class test {public static void main(String[] args) { BeautifulGirl girl = new BeautifulGirl(); girl.setName("娇妹"); LaoWang proxy = new LaoWang(girl); System.out.println(proxy.sayHello()); System.out.println(proxy.doMyGirlFriend()); //娇妹 你好,我是一个大帅比! //娇妹 做我女朋友吧!}}
这样,我们就通过老王成功的向娇妹打招呼了。
动态代理
在Spring中,AOP的实现离不开动态代理。而实现动态代理又可通过jdk或者cglib来实现。
jdk动态代理是由java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。
JDK动态代理
使用jdk动态代理需要基于接口编程
public interface HelloService { void sayHello();}
public class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("Hello World!"); }}
/** * 使用此种方法动态代理对象需要基于接口编程 */public class HelloServiceJdkProxyFactory implements InvocationHandler { //需要被代理的目标对象 private HelloService helloService; public HelloServiceJdkProxyFactory(HelloService helloService) { this.helloService = helloService; } //生成代理对象 public HelloService newProxyInstance() { /** * loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 */ return (HelloService) Proxy.newProxyInstance(helloService.getClass().getClassLoader(), helloService.getClass().getInterfaces(), this); } /** * @param proxy 被代理的对象 * @param method 要调用的方法 * @param args 方法调用时所需要参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before hello world"); //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 Object o = method.invoke(helloService, args); System.out.println("after hello world"); return o; }}
@Test public void jdkProxyTest() { HelloService helloService = new HelloServiceImpl(); HelloServiceJdkProxyFactory proxy = new HelloServiceJdkProxyFactory(helloService); proxy.newProxyInstance().sayHello(); }
测试结果:
before hello world
Hello World !
after hello world
CGlib动态代理
/** * Cglib动态代理,需要cglib包和asm依赖包 **/public class HelloServiceCglibProxyFactory implements MethodInterceptor { public Object newProxyInstance(Class c) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(c); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("before hello world"); Object invoke = methodProxy.invokeSuper(o, objects); System.out.println("after hello world"); return invoke; }}
@Test public void cglibProxyTest() { HelloServiceCglibProxyFactory proxy = new HelloServiceCglibProxyFactory(); HelloService helloService = (HelloService) proxy.newProxyInstance(HelloServiceImpl.class); helloService.sayHello(); }
测试结果:
before hello world
Hello World !
after hello world
那么什么样的需求时候适合使用代理模式呢?
代理模式的使用场景:
远程代理:也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
虚拟代理:如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。通过它来存放需要很长时间的真实对象
安全代理:控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
智能代理,指当调用真实的对象时,代理处理另外一些事。如计算真实对象的引用次数,当该对象没有引用时,可以自动释放它。
源码链接
本文地址:http://blog.csdn.net/ProdigalWang/article/details/75675756
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之-代理模式
- 设计模式之 代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之-----代理模式
- 设计模式之代理模式
- 设计模式之-代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- Example 3.8:Gridworld
- 17_7_21 二叉树的层序遍历
- IO操作练习实例——文件的创建
- D_D系统构建-MBR(7)加载loader文件代码filesystem.inc解析
- Head First Python(中文版)pdf
- 设计模式之代理模式
- 【剑指offer】面试题28:对称的二叉树
- c语言数据结构复习(一)
- git--配置别名
- Kubernetes核心原理(二)之Controller Manager
- Spring 3.x 企业应用开发实战pdf
- 属性节点的属性和方法
- ls命令的自己实现
- python web开发学习实录pdf