Java 动态代理介绍及用法

一,静态代理模式的特点

在之前的文章中 Java代理模式 已经介绍里Java里的(静态)代理模式

下面是上文静态代理类的例子:

public class ProxyBear implements Hitable<Dog>{ private Hitable<Dog> f = null; public ProxyBear(){ if (null == f){ f = new Fox(); } } @Override public void hit(Dog g){ if (null != f){ System.out.println("Bear hit InterDogChicken!"); f.hit(g); System.out.println("Bear bite InterDogChicken!"); } }

从代码可以看出, 上面代理类可以增强被代理的对象的某个方法。
但是被代理对象的类型Hitable是指定1个接口(或抽象类)

也就是讲上静态代理类只适用于某一种指定的接口实现类, 如果某个对象没有实现揍狗接口, 而是其他另1个接口, 那么就必须新建1个代理类的。即使新代理类也是实现同样的功能

二. 动态代理的1个需求

就用会上文的例子

我们宜家有两个接口。殴打和调戏接口..

殴打接口 Hitable public interface Hitable<T> { public void hit(T o); } 调戏接口 Molestable public interface Molestable<T> { public void molest(T o); } 其中狐狸类实现了殴打狗接口 public class Fox implements Hitable<Dog> { @Override public void hit(Dog g){ this.sap(g); this.uppercut(g); } //闷棍 private void sap(Dog g){ System.out.println("give " + g.getName() + " a Sap!"); } //上勾拳 private void uppercut(Dog g){ System.out.println("give " + g.getName() + " a Uppercute!"); } } 狼类实现调戏狗接口 public class Wolf implements Molestable<Dog> { @Override public void molest(Dog o) { System.out.println("wolf laugh at the dog!"); System.out.println("wolf ruffle the dog!"); } } 这个是万恶的狗类 public class Dog { private String name; public Dog(String name){ this.setName(name); } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Dog [name=" + name + "]"; } } 问题来了, 依家狗太恶, 狼和狐狸都要找头熊(代理)看着才敢去惹狗

如果用静态代理, 就如本文一开始的那个代理类, 则只能单独为狐狸or 狼代理, 这个需求需要两个代理类, 因为狗和狐狸实现的是两个不同的接口

如下图

Alt text

那么有没有一种代理类, 可以同时代理多个接口的实现类呢,java 里动态代理就利用了反射实现了这个功能。

三,动态代理的例子

我们利用动态代理类重新写了1个熊类出来:

public class dynamicProxyBear implements InvocationHandler { //delegate means proxy //the object which will be delegated private Object delegate; public Object bind(Object delegate){ this.delegate = delegate; /** * This method newProxyInstance return ***one of the interfaces*** of delegate object(properties object of this class) * * @param * 1.ClassLoader loader -> usually use delegate object's class loader * 2.Class<?>[] interfaces -> collection of the interface which delegate object has implemented * 3.InvocationHandler h -> this * @return */ return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this); } /** * This method will replace all the method owned by delegate object. * @param proxy -> the delegate object, never use it's method directly, otherwise will lead to Dead loop * @param method -> the method (once execute will fall into this invoke method) object of delegate object * @param args -> parameters of the mothod. * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result; if (args.length < 1){ return method.invoke(this.delegate,args); } //bear watching System.out.println("bear is watching " + args[0].toString()); result = method.invoke(this.delegate,args); System.out.println("bear leaved " + args[0].toString()); return result; } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1ffbd36c388032b618cb4062d6e7bb95.html