首页 > 代码库 > Java代理模式

Java代理模式

  关于代理模式的概念: 

  用现在相当热门的宝强马蓉事件做比喻,宝强相当于是被代理类,宋喆就是代理类,宋喆代理着宝强的许多行为,宋喆对宝强的消息进行预处理、过滤、转发、公关等。就如公关,当宝强需要公关的时候宝强无须真正亲自去实现公关,真正实现的是由宋喆代理完成。
  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类     与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 
 
  静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 
  动态代理:在程序运行时,运用反射机制动态创建而成。 

首先我们使用代码来讲解静态代理:

以下是IStar类型接口,也就是明星该有的行为:

1 public interface IStar{2    //努力工作3    void hardWork;4   //爱妻子5    void loveWife;6 }

以下是IStar接口的实现类Satr

public class Star implementsIStar{    private String mName;    public Star(String mName){      mName=this.mName;    }    public void hardWork(){     System.out.printf(this.mName+"努力工作");}    public void loveWife(){     System.out.printf(this.mName+"爱护妻子");}    }

经纪人代表的是明星,所以从某种意义上讲与明星具有相同的行为

public class Agent implements IStar{   //需要代理的对象    IStar mIStar;   //代理类的一个成员变量    boolean mIsHappy;    public Agent(IStar IStar){      mIStar=IStar;    }    public Agent(IStar IStar,boolean isHappy){      mIStar=IStar;      mIsHappy=isHappy;    }   //与被代理类具有相同方法    public void hardWork(){     mIStar.hardWork;}  //此时代理类也可以改变被代理类的行为方法    public void loveWife(){     if(mIsHappy){     mIStar.loveWife;   }else{     System.out.printf("经纪人造反");   }}    }

测试类

 

public class test{   public static void main(String[] args){  //在此新建一个被代理对象  是明星王宝强   Star baoqiang=new Star("王宝强");  //告诉经纪人  他需要代理的对象是明星王宝强  并且将经济人IsHappy属性设           // 为false   Agent songjj =new Agent(baoqiang,false);   songjj.hardWrok();   songjj.loveWife();}}

输出结果:王宝强努力工作

              经纪人造反

 

 以上是静态代理的例子,有助于代码的解耦。

接下来是动态代理模式:

 要求如下:使用java代码完成整数加减乘除算法器,并且

1、在程序执行期间追踪正在发生的活动

2、希望计算器只能处理正数的运算

 

为了是的代码的集中与不混了我们使用动态代理模式实现

首先是创建一个接口

1 public interface ArithmeticCalculator {2 3     int add(int i, int j);4     int sub(int i, int j);5     6     int mul(int i, int j);7     int div(int i, int j);8     9 }

其次是实现ArithmeticCalculator接口

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {    @Override    public int add(int i, int j) {        int result = i + j;        return result;    }    @Override    public int sub(int i, int j) {        int result = i - j;        return result;    }    @Override    public int mul(int i, int j) {        int result = i * j;        return result;    }    @Override    public int div(int i, int j) {        int result = i / j;        return result;    }}

穿件代理类ArithmeticCalculatorLoggingProxy

 1  1 package com.atguigu.spring.aop; 2  2  3  3 import java.lang.reflect.InvocationHandler; 4  4 import java.lang.reflect.Method; 5  5 import java.lang.reflect.Proxy; 6  6 import java.util.Arrays; 7  7  8  8 public class ArithmeticCalculatorLoggingProxy { 9  9     10 10     //要代理的对象11 11     private ArithmeticCalculator target;12 12     13 13     public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {14 14         super();15 15         this.target = target;16 16     }17 17 18 18     //返回代理对象19 19     public ArithmeticCalculator getLoggingProxy(){20 20         ArithmeticCalculator proxy = null;21 21         //获取要代理对象的加载器22 22         ClassLoader loader = target.getClass().getClassLoader();23 23         Class [] interfaces = new Class[]{ArithmeticCalculator.class};24 25 24         InvocationHandler h = new InvocationHandler() {26 25             /**27 26              * proxy: 代理对象。 一般不使用该对象28 27              * method: 正在被调用的方法29 28              * args: 调用方法传入的参数30 29              */31 30             @Override32 31             public Object invoke(Object proxy, Method method, Object[] args)33 32                     throws Throwable {34 33                 String methodName = method.getName();35 34                 //打印日志36 35                 System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args));37 36                 38 37                 //调用目标方法39 38                 Object result = null;40 39                 41 40                 try {42 41                     //前置通知43 42                     result = method.invoke(target, args);44 43                     //返回通知, 可以访问到方法的返回值45 44                 } catch (NullPointerException e) {46 45                     e.printStackTrace();47 46                     //异常通知, 可以访问到方法出现的异常48 47                 }49 48                 50 49                 //后置通知. 因为方法可以能会出异常, 所以访问不到方法的返回值51 50                 52 51                 //打印日志53 52                 System.out.println("[after] The method ends with " + result);54 53                 55 54                 return result;56 55             }57 56         };58 57         59 58         /**60 59          * loader: 代理对象使用的类加载器。 61 60          * interfaces: 指定代理对象的类型. 即代理代理对象中可以有哪些方法. 62 61          * h: 当具体调用代理对象的方法时, 应该如何进行响应, 实际上就是调用 InvocationHandler 的 invoke 方法63 62          */64 63         proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);65 64         66 65         return proxy;67 66     }68 67 }

 

测试类

 

 1 package com.atguigu.spring.aop; 2  3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5  6 public class Main { 7      8     public static void main(String[] args) { 9         ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl();10         11         arithmeticCalculator = 12                 new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy();13         14         int result = arithmeticCalculator.add(11, 12);15         System.out.println("result:" + result);16         17         result = arithmeticCalculator.div(21, 3);18             System.out.println("result:" + result);19         20     }21     22 }

 

Java代理模式