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  package com.atguigu.spring.aop;
 2  
 3  import java.lang.reflect.InvocationHandler;
 4  import java.lang.reflect.Method;
 5  import java.lang.reflect.Proxy;
 6  import java.util.Arrays;
 7  
 8  public class ArithmeticCalculatorLoggingProxy {
 9     
10      //要代理的对象
11      private ArithmeticCalculator target;
12     
13      public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
14          super();
15         this.target = target;
16      }
17  
18      //返回代理对象
19      public ArithmeticCalculator getLoggingProxy(){                          ArithmeticCalculator proxy = null;
20          //获取要代理对象的加载器
21          ClassLoader loader = target.getClass().getClassLoader();
22         Class [] interfaces = new Class[]{ArithmeticCalculator.class};
23  
24          InvocationHandler h = new InvocationHandler() {
25              /**
26               * proxy: 代理对象。 一般不使用该对象
27              * method: 正在被调用的方法
28              * args: 调用方法传入的参数
29               */
30             @Override
31             public Object invoke(Object proxy, Method method, Object[] args)
32                     {
33                 String methodName = method.getName();
34                  //打印日志
35                  System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args));
36                  
37                  //调用目标方法
38                  Object result  = method.invoke(target, args);
39                  
40                 //打印日志
41                  System.out.println("[after] The method ends with " + result);
42                  return result;
43              }
44          };
45          
46          /**
47           * loader: 代理对象使用的类加载器。 
48           * interfaces: 指定代理对象的类型. 即代理代理对象中可以有哪些方法. 
49           * h: 当具体调用代理对象的方法时, 应该如何进行响应, 实际上就是调用 InvocationHandler 的 invoke 方法
50           */
51          proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
52          
53          return proxy;
54      }
55  }

 

 

测试类

 

 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 }

 

posted @ 2016-08-29 01:48  1234ztc  阅读(320)  评论(0编辑  收藏  举报