一,静态代理模式的特点
在之前的文章中 Java代理模式 已经介绍里Java里的(静态)代理模式 http://www.linuxidc.com/Linux/2016-12/138191.htm
下面是上文静态代理类的例子:
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 狼代理, 这个需求需要两个代理类, 因为狗和狐狸实现的是两个不同的接口
如下图
那么有没有一种代理类, 可以同时代理多个接口的实现类呢,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;
}
}
更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2016-12/138192p2.htm