JAVA设计模式---代理模式

来源:互联网 发布:python计算器 界面 编辑:程序博客网 时间:2024/06/07 06:21

一、什么是代理模式

代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.

二、静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.

代码示例:

IUserDao.java

/** * 接口 */public interface IUserDao {    void save();}
⑵UserDao.java

/** * 接口实现 * 目标对象 */public class UserDao implements IUserDao {    public void save() {        System.out.println("----已经保存数据!----");    }}
⑶UserDaoProxy.java

/** * 代理对象,静态代理 */public class UserDaoProxy implements IUserDao{    //接收保存目标对象    private IUserDao target;    public UserDaoProxy(IUserDao target){        this.target=target;    }    public void save() {        System.out.println("开始事务...");        target.save();//执行目标对象的方法        System.out.println("提交事务...");    }}
App.java

/** * 测试类 */public class App {    public static void main(String[] args) {        //目标对象        UserDao target = new UserDao();        //代理对象,把目标对象传给代理对象,建立代理关系        UserDaoProxy proxy = new UserDaoProxy(target);        proxy.save();//执行的是代理的方法    }}

静态代理总结:
1.可以做到在不修改目标对象的功能前提下,对目标功能扩展.
2.缺点:

因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.

三、JDK动态代理

1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理

代码示例:

BookFacade.java 

package net.battier.dao;    public interface BookFacade {      public void addBook();  }  
BookFacadeImpl.java 

package net.battier.dao.impl;    import net.battier.dao.BookFacade;    public class BookFacadeImpl implements BookFacade {        @Override      public void addBook() {          System.out.println("增加图书方法。。。");      }    }  
BookFacadeProxy.java  

package net.battier.proxy;    import java.lang.reflect.InvocationHandler;  import java.lang.reflect.Method;  import java.lang.reflect.Proxy;    /**  * JDK动态代理代理类  *   * @author student  *   */  public class BookFacadeProxy implements InvocationHandler {      private Object target;      /**      * 绑定委托对象并返回一个代理类      * @param target      * @return      */      public Object bind(Object target) {          this.target = target;          //取得代理对象          return Proxy.newProxyInstance(target.getClass().getClassLoader(),                  target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)      }        @Override      /**      * 调用方法      */      public Object invoke(Object proxy, Method method, Object[] args)              throws Throwable {          Object result=null;          System.out.println("事物开始");          //执行方法          result=method.invoke(target, args);          System.out.println("事物结束");          return result;      }    }  
TestProxy.java 

package net.battier.test;    import net.battier.dao.BookFacade;  import net.battier.dao.impl.BookFacadeImpl;  import net.battier.proxy.BookFacadeProxy;    public class TestProxy {        public static void main(String[] args) {          BookFacadeProxy proxy = new BookFacadeProxy();          BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());          bookProxy.addBook();      }    }  
输出:
事物开始
增加图书方法。。。
事物结束

四、Cglib动态代理 

如果一个类没有实现接口,那么只能用Cglib动态代理 了

代码示例:

BookFacadeCglib.java 

package net.battier.dao;    public interface BookFacade {      public void addBook();  }  
BookCadeImpl1.java 

package net.battier.dao.impl;    /**  * 这个是没有实现接口的实现类  *   * @author student  *   */  public class BookFacadeImpl1 {      public void addBook() {          System.out.println("增加图书的普通方法...");      }  }  
BookFacadeProxy.java 

package net.battier.proxy;    import java.lang.reflect.Method;    import net.sf.cglib.proxy.Enhancer;  import net.sf.cglib.proxy.MethodInterceptor;  import net.sf.cglib.proxy.MethodProxy;    /**  * 使用cglib动态代理  *   * @author student  *   */  public class BookFacadeCglib implements MethodInterceptor {      private Object target;        /**      * 创建代理对象      *       * @param target      * @return      */      public Object getInstance(Object target) {          this.target = target;          Enhancer enhancer = new Enhancer();          enhancer.setSuperclass(this.target.getClass());          // 回调方法          enhancer.setCallback(this);          // 创建代理对象          return enhancer.create();      }        @Override      // 回调方法      public Object intercept(Object obj, Method method, Object[] args,              MethodProxy proxy) throws Throwable {          System.out.println("事物开始");          proxy.invokeSuper(obj, args);          System.out.println("事物结束");          return null;          }    }  
TestCglib.java 

package net.battier.test;    import net.battier.dao.impl.BookFacadeImpl1;  import net.battier.proxy.BookFacadeCglib;    public class TestCglib {            public static void main(String[] args) {          BookFacadeCglib cglib=new BookFacadeCglib();          BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());          bookCglib.addBook();      }  }