捞逼205文集。程序员

Java 动态代理(1)

2017-10-08  本文已影响22人  e244fad16d0f

代理模式即Proxy Pattern,23种常用的面向对象软件的设计模式之一。 Java的动态代理比代理的思想更像前迈进了一步,因为他可以动态的代理并且动态的处理对代理方法的调用。在动态代理商的所作的所有调用都会被重新定向定义到单一的调用处理器上,它的工作是揭示调用类型并确定相对应的对策 ( 上面都是Thinking in Java 上面说的

举个例子

public class Clerk {
   public int sell() {
       System.out.print("店铺上新");
       return 0;
   }
}

public class Shop {
   private Clerk clerk;
   public void sell() {
       clerk.sell();
   }
}

上述例子在运行shop的sell方法的时候会输出 “店铺上新” ,如果我们要修改clerk说的话或者修改别的,那样子就要修改Clerk类,我们知道这样很不优雅,所以我们把Clerk的实现变为interface,如果将来需要扩展的话,我们实现这个Clerk接口就行了,接着我们还可以做一个代理Clerk,将我们需要调用的Clerk传过去,让代理Clerk来进行sell操作,在这个sell方法的前后添加代码,但是不改动原有代码。是不是很优雅?

interface Clerk {
   int sell();
}

public class NewClerk implements Clerk {

   public int sell() {
        System.out.println("店铺上新啊");
        return 0;
   }

}

public class ProxyClerk implements Clerk {

   private Clerk clerk;
   public ProxySellFisher(Clerk clerk) {
       this.clerk = clerk;
   }
   public int sellFish() {
       System.out.println("双十一优惠???");
       return sell.sellFish();
   }

}

上面讲的其实都是设计模式的代理,别的语言其实也行,重点其实是Java的动态代理,为什么说Java的动态代理比代理模式要优雅呢,因为Java在Proxy类中已经实现了这个模式,只不过它叫动态代理,因为它的代理类名字叫InvocationHandler了,执行的方法是invoke,再举个🌰 ???顺便引用下百度百科动态代理和静态代理的区别

静态代理是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

public class NewClerk implements Clerk {
   public int sell() {
       System.out.println("店铺上新啊");
       return 0;
   }
}

public class ProxyClerk implements InvocationHandler {

   private Clerk clerk;

   public ProxyClerk(Clerk clerk) {
           this.clerk = clerk;
       }

   @Override
   public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
       System.out.println("双十一优惠???");
       return (Integer) method.invoke(sell, args);
   }

}

public class ShopCase {
   public static void main(String args[]) {
       NewClerk c = new NewClerk();
       InvocationHandler p = new ProxyClerk(c);
       NewClerk obj =(NewClerk)  Proxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(), p);
       obj.sell();
   }
}

上述代码实现了一个接口InvocationHandler,并重写了它的invoke方法 这个方法利用java反射机制对传入的对象调用了sell方法

NewClerk obj =(NewClerk) Proxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(), p);

当我们执行这条语句的时候,会把c下面的方法在p里面添加了代理。最后由newProxyInstance 返回生成的对象。

最后感觉依赖注入其实和代理模式有点像诶。

上一篇 下一篇

猜你喜欢

热点阅读