Java設計模式---代理模式(二)---動態代理
阿新 • • 發佈:2018-11-29
動態代理
動態代理和代理模式實質是一樣的,只是要更加靈活。
代理模式請見本部落格另一篇文章 ”Java設計模式---代理模式(一)“例、
房東介面:
package cn.hncu.pool.day2.proxy.demo1;
public interface IRenter {
public void rent(int i);
}
房東:
客戶:package cn.hncu.pool.day2.proxy.demo1; public class Renter implements IRenter{ @Override public void rent(int i) { System.out.println("給你"+i+"個房間,請交500元!"); } @Override public String toString() { System.out.println("Renter:你好,我是房東,房子請不要搬走..."); return "Renter:你好,我是房東,房子請不要搬走..."; } }
上面這個客戶程式碼中客戶的類載入器Client.class.getClassLoader()必須要和被代理人的介面的class集(new Class[]{IRenter.class} )處於相同的生存空間,否則無效package cn.hncu.pool.day2.proxy.demo1; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { final IRenter r = new Renter();//被代理的物件 //r.rent(); Object obj = Proxy.newProxyInstance( Client.class.getClassLoader(), new Class[]{IRenter.class}, new InvocationHandler() { @Override//proxy是代理後的物件(等價於返回的obj), method就是類反射中的方法物件, args是執行method方法所需的引數 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是中介,收點錢......."); Object oo= method.invoke(r, args); //r.xxx(args)---放行 System.out.println("歡迎下次再來找我中介....."); return oo; } }); //上一句返回的obj就是代理後的物件 IRenter rr = (IRenter) obj; rr.rent(3); } }
此外,還可以判斷方法名,可以修改方法內容
Object obj = Proxy.newProxyInstance( Client2.class.getClassLoader(), new Class[]{IRenter.class}, new InvocationHandler() { @Override//proxy是代理後的物件(等價於返回的obj), method就是類反射中的方法物件, args是執行method方法所需的引數 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { Object oo = null; if(method.getName().equals("rent")){ <span style="white-space:pre"> </span>System.out.println("我是中介,收點錢......."); <span style="white-space:pre"> </span>oo= method.invoke(r, args); //r.xxx(args)---放行 <span style="white-space:pre"> </span>System.out.println("歡迎下次再來找我中介....."); }else{ oo= method.invoke(r, args);//放行 } return oo; } });
或者也可以將InvocationHandler寫到其他地方
1、
package cn.hncu.pool.day2.proxy.demo2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class ProxyDemo2 {
public static void main(String[] args) {
Object proxiedObj = Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader(),
new Class[]{List.class},
new A());
List list = (List)proxiedObj;
list.add(100);
list.add("abc");
System.out.println(list.size());
System.out.println(list.get(1));
}
static class A implements InvocationHandler{
private List list = new ArrayList();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("您現在執行的是"+method.getName()+"方法...");
return method.invoke(list, args);
}
}
}
2、
package cn.hncu.pool.day2.proxy.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil implements InvocationHandler {
private Object srcObj = null;
public ProxyUtil(Object srcObj){
this.srcObj = srcObj;
}
public static Object getProxy(Object srcObj){
Object obj = Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),
srcObj.getClass().getInterfaces(),
new ProxyUtil(srcObj) );
return obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("在工具類中被攔截.......");
Object returnObj = method.invoke(srcObj, args);
System.out.println("在工具類中攔截之後.......");
return returnObj;
}
}