前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >代理模式

代理模式

作者头像
高爽
发布2017-12-28 12:11:33
4760
发布2017-12-28 12:11:33
举报
文章被收录于专栏:高爽的专栏高爽的专栏

概述

代理模式,即ProxyPattern,java常用设计模式之一,动态代理实现了著名的AOP思想。代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。

通俗的讲,可以拿到现实中来举例,可能说的并不准确,比如,苹果出了一款iphone手机,拿到中国交给代理商来卖,如联通、电信,就是所谓的定制机,联通电信又给iphone手机植入了一些软件,再卖给使用者。我们最后买到的手机就是代理商处理过的。

静态代理

静态代理很好理解,代码类似如下:

原类:

package staticProxy;public class Object {   public void service() {      // do something   }}

代理类:

package staticProxy;public class ProxyObject {   private staticProxy.Object obj;   public ProxyObject(staticProxy.Object obj) {      this.obj = obj;   }   public void service() {      // do something      this.obj.service();   }}

静态代理需要对每个原类创建一个代理类,这样做需要代理的情况少的话还可以接受,如果多的话,就无法接受了,所以我们需要一种动态创建代理类的方式。

动态代理

Java支持动态代理,可以在运行期根据原对象来动态创建代理对象。有两种方式可以实现动态代理,一种是通过JDK Proxy,另一种是第三方类库CGLIB,前者得到的代理对象是实现和原类相同的接口,后者得到的是继承自原类。下面主要介绍的是JDK Proxy。

Proxy类中有个newProxyInstance方法,可以通过该方法得到代理对象,该方法有三个参数:

ClassLoader loader:原类的类加载器;

Class[] interfaces:原类实现的接口列表;

InvocationHandler handler:指派方法调用的调用处理程序。

调用该方法创建代理对象时,会把InvocationHandler传入$Proxy内,并根据相应接口生成方法,每个方法内都调用InvocationHandler中的invoke方法,在invoke方法中执行相应方法。

原理图

实现

Advice.java,增强类,用于创建代理对象时增强功能。

public class Advice {   /** 前置增强 */   public void beforeMethod() {      System.out.println("前置增强");   }   /** 后置增强 */   public void afterMethod() {      System.out.println("后置增强");   }   /** 异常增强 */   public void catchMethod() {      System.out.println("异常增强");   }   /** 最后执行增强 */   public void finallyMethod() {      System.out.println("最后增强");   }}

ProxyFactory.java,代理类工厂,用于产生代理对象。

public class ProxyFactory {   /** 代理类的增强对象 */   private Advice advice;   /** 代理的目标对象 */   private Object target;   public ProxyFactory() {}   public ProxyFactory(Advice advice, Object target) {      this.advice = advice;      this.target = target;   }   /**    * 得到代理对象    * @return    */   public Object getProxy() {      Object proxy = Proxy.newProxyInstance(           target.getClass().getClassLoader(),           target.getClass().getInterfaces(),new InvocationHandler() {              /**               * 代理对象需要执行的方法               */              public Object invoke(Object proxy, Method method, Object[] args) {                 Object result = null;                 advice.beforeMethod();                 try {                    result = method.invoke(target, args);                    advice.afterMethod();                 } catch (Exception e) {                    advice.catchMethod();                 } finally {                    advice.finallyMethod();                 }                 return result;              }           });      return proxy;   }   public void setAdvice(Advice advice) {      this.advice = advice;   }   public void setTarget(Object target) {      this.target = target;   }}

ITest.java,目标对象接口。

public interface ITest {   void test();}

Test.java,目标对象类。

public class Test implements ITest {   public void test() {      System.out.println("目标对象");   }   public static void main(String[] args) {      ProxyFactory pf = new ProxyFactory(new Advice(), new Test());      ITest test = (ITest) pf.getProxy();      test.test();   }}

输出结果:

前置增强目标对象后置增强最后增强

总结

动态代理实现了AOP思想,AOP弥补了OOP的不足。本篇主要介绍的是jdk proxy动态代理的使用方式,对AOP没有特意说明。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2012-12-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 静态代理
  • 动态代理
  • 原理图
  • 实现
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档