设计模式之----代理模式

代理模式

1. 什么是代理模式?
  代理模式是GoF四人组提出的23种设计模式之一。
  若一个类T不能或不适合让另外一个类C直接访问,或者,类T在不修改自身源码的前提下,想增强业务逻辑功能,
  此时,就可以通过一个中间类P来完成这些需求。那么,这个中间类P就称为代理类,而类T则称为目标类。
  换个角度思考,那就是说,客户类C若想与目标类T打交道,那么都需要通过代理类P来完成。即客户类只能与代理
  类P发生直接的联系。代理类P的对象可以代表目标类T与客户类打交道。

  

2. 代理模式中的角色
  目标类  代理类  客户类

3. 代理模式的目的
  1)为了保护和隐藏某一个类,可以使用代理模式
  2)在不修改某个类的源码的前提下,为了增强某个类的功能,可以使用代理模式

4. 代理模式的分类
  根据代理类创建的时间的不同,或者说,根据代理关系确立的时机的不同,可以将代理模式分为两类
  1)静态代理
  2)动态代理
  动态代理又根据实现技术的不同,可以分为若干类,例如:
  1)JDK的动态代理: 

    原理:  Proxy底层利用接口创建了代理类对象,  当内存中已经有时,会创建一个副本,,  自定义类为委托类....  

    使用要求:.有接口才能使用代理 
      ①自定义类实现(实现委托类), 需实现InvocationHandler 接口实现委托功能(对方法进行挑选过滤增强)

 1//创建委托类
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5         //    jdk自带的proxy委托需实现InvocationHandler接口
 6 public class BookProxy implements InvocationHandler {
 7     private BookDao bookDao;//目标类对象
 8     public BookProxy(BookDao bookDao) {
 9         super();
10         this.bookDao = bookDao;
11     }
12     //    proxy 代理类(一般不用,使用错误会导致死循环)
13     // Method 方法(反射中的方法对象)
14     // args  传参
15     @Override
16     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
17         // TODO Auto-generated method stub
18         if (method.getName().equals("insert")) {
19             //使用实现类对象用反射调用方法
20             Object invoke = method.invoke(bookDao,args);
21             return invoke;
22         }
23         return null;
24     }
25 }

    ②main方法中使用Proxy.newProxyInstance方法获取代理类

public class Demo {
public static void main(String[] args) {
    IbookDao instance = (IbookDao)Proxy.newProxyInstance(    //返回值为一个代理类对象  (强转为接口)
                                            Demo.class.getClassLoader(),    //目标类的类加载器
                                            BookDao.class.getInterfaces(), //目标类的实现接口
                                            new BookProxy(new BookDao()));//委托类对象
    instance.insert();                //调用接口中的方法,(实现类中的方法)
}
}

  ③目标类中实现接口

public class BookDao implements IbookDao {
  .....//实现IbookDao中的方法  
}

 

  2)CGLIB动态代理:  

    原理 :底层创建一个实现类的子类对象

   使用要求: 导入cglib包

      ①:自定义类(实现委托类).  实现MethodInterceptor接口(此接口实现了callback回调接口,标识作用)

public class Cglib implements MethodInterceptor{
    private BookDao book;    //目标类对象
    public Cglib(BookDao book) {
        super();
        this.book = book;
    }
        //obj代理类对象
        // method    反射方法
        //    args 参数
        // proxy    实现方法的代理类对象
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // TODO Auto-generated method stub
                 method.invoke(book, args);
                 return null;
    }
}

    ②main调用    需自己创建调用类对象及方法

public class Demo {
public static void main(String[] args) {
    BookDao book= new BookDao();    //目标类
    Cglib cglib = new Cglib(book);    //委托类
                          //此类需要自己创建    
    BookDao bookDao = (BookDao)CreateProxy.newProxyInstance(  //返回值即为目标类的子类对象
                                            BookDao.class,     //实现类的字节码文件对象
                                                cglib);    //委托类对象
    bookDao.delet();
    }
}

    ③创建调用类,与方法..方法名与Proxy中的一样

public class CreateProxy {
    public static Object newProxyInstance(Class class1, MethodInterceptor cglib) {
        //新建增强器对象
        Enhancer enhancer = new Enhancer();
        //设置父类,,,即目标类
        enhancer.setSuperclass(class1);
        //设置委托类
        enhancer.setCallback(cglib);
        //创建并返回
        return enhancer.create();
    }
}

   


  3)Javassist动态代理

    ............

 

 

posted @ 2017-08-26 13:22  Roomed  阅读(241)  评论(0编辑  收藏  举报