在之前的文章中 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個代理類的。即使新代理類也是實現同樣的功能
就用會上文的例子
我們宜家有兩個接口。毆打和調戲接口..
public interface Hitable<T> {
public void hit(T o);
}
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