动态代理模式分析

来源:互联网 发布:matlab2016b mac 编辑:程序博客网 时间:2024/06/17 17:53

一.java动态代理模式

由于静态代理需要在运行之前就需要写好代理类,这样就造成了大量重复代码,

从JDK1.3开始,java中引入了动态代理机制。相关的接口或类有如下两个:InvocationHandler接口和Proxy类,都位于java.lang.reflect包下。

Java反射机制动态生成代理类无需程序员手工编写不仅简化了编程工作,而且提高了软件系统的可扩展性可以生成任意类型的动态代理类。

InvocationHandler接口只定义了一个抽象方法:
        Object invoke(Object proxy, Method method, Object[] args)

参数说明: 
          Object proxy:指被代理的对象。 
          Method method:要调用的方法 
          Object[] args:方法调用时所需要的参数 

      可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject(代理主题)。

Proxy类静态方法:


                                  ObjectnewProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

参数说明: 
           ClassLoader loader:类加载器 
          Class<?>[] interfaces:得到全部的接口 

          InvocationHandler h:得到InvocationHandler接口的子类实例

下面用代码举例说明

第一:需要定义业务ISubject接口,IDataOperation接口,IHotel接口,IPlay接口,

package proxy;public interface IDataOperation {public void add();public void delete();public void update();public void find();}
package proxy;public interface IHotel {public void live();}

package proxy;public interface IPlay {public void play();}

package proxy;public interface ISubject extends IHotel, IPlay, IDataOperation {public void doSomething();}


第二:定义代理类,即代理主题ProxyImpl动态代理


package proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProxyImpl implements InvocationHandler {    private Object real; //将实际主题和代理主题解耦合        public Object bind(Object obj){  // 真正要执行业务的对象         this.real = obj;                 //取得代理对象         return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);    }        public void prepare(){        System.out.println("*******准备工作");    }        public void clean(){        System.out.println("**********清理工作");    }        @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        this.prepare();                Object ret = method.invoke(real, args);        this.clean();        return ret;    }}
在上面的代码中,代理类ProxyImpl 实现了JDK提供的InvocationHander接口, 不用实现具体的某个业务接口。

可以通过newProxyInstance 为一个或多个接口动态地生成实现类


第三:定义实际类,即实际主题RealSubject(可以理解为只关心结果)


package proxy;public class RealSubject implements ISubject, IHotel, IPlay, IDataOperation {@Overridepublic void add() {System.out.println("...添加业务...");}@Overridepublic void delete() {System.out.println("...删除业务...");}@Overridepublic void update() {System.out.println("...更新业务...");}@Overridepublic void find() {System.out.println("...查找业务...");}@Overridepublic void play() {System.out.println("...开心的玩...");}@Overridepublic void live() {System.out.println("...住酒店...");}@Overridepublic void doSomething() {System.out.println("...开始吃饭...");}}

第四:客户端即测试类


package proxy;public class TestDynamic {public static void main(String[] args) {ProxyImpl proxy = new ProxyImpl();// 传入真正的对象  new RealSubject()ISubject subject = (ISubject) proxy.bind(new RealSubject());subject.doSomething();subject.live();subject.play();subject.add();subject.delete();subject.update();subject.find();}}


原创粉丝点击