代理模式,個(gè)人認(rèn)為就是把你要使用的一個(gè)對(duì)象盡享封裝,包裝。編程原對(duì)象的一個(gè)副本,在使用的時(shí)候直接使用他這個(gè)副本就可以了!他的作用用專業(yè)點(diǎn)的語(yǔ)言描
述就是為其他的對(duì)象提供一個(gè)代理方便控制這個(gè)對(duì)象。當(dāng)我們不能直接調(diào)用另外一個(gè)對(duì)象,但是又不得不用這個(gè)對(duì)象的某些功能,此時(shí)代理對(duì)象就能起到鏈接客戶和
目標(biāo)對(duì)象的一個(gè)代理.
代理模式一般涉及到三個(gè)角色,分別為:
1. 抽象角色:他提供真實(shí)對(duì)象和代理對(duì)象的共同接口。
2. 代理角色:通俗地說(shuō),代理角色是對(duì)原對(duì)象(目標(biāo)對(duì)象)進(jìn)行包裝,他有著和原對(duì)象相同的接口,并且可以執(zhí)行真實(shí)對(duì)象的操作。
3. 真實(shí)角色:即目標(biāo)對(duì)象,最終我們需要對(duì)他的操作。
代理模式分為兩種,一 靜態(tài)代理,二 動(dòng)態(tài)代理。
接下來(lái)我們介紹一下兩種代理模式:
一 靜態(tài)代理
靜態(tài)代理即 代理對(duì)象和被代理對(duì)象在代理之前已經(jīng)確定好了。他們一起實(shí)現(xiàn)相同的接口或者是繼承相同的抽象類。例如:
-
- public abstract class AbsRole{
- abstract public void work();
- }
//定義抽象角色
public abstract class AbsRole{
abstract public void work();
}
-
- public class RealRole extends AbsRole{
- public RealRole(){ }
-
- public void work(){
- System.out.println("調(diào)用真實(shí)角色中函數(shù)!");
- }
- }
//定義真實(shí)角色
public class RealRole extends AbsRole{
public RealRole(){ }
public void work(){
System.out.println("調(diào)用真實(shí)角色中函數(shù)!");
}
}
-
- public class ProxyRole extends AbsRole{
- public RealRole real ;
-
- public ProxyRole(){
- }
-
- public void work(){
- this.beforeMethod();
- if(real == null){
- real = new RealRole();
- }
- real.work();
- this.endMethod();
- }
-
- public void beforeMethod(){
- System.out.println("代理前執(zhí)行函數(shù)->beforeMethod()");
- }
-
- public void endMethod(){
- System.out.println("代理時(shí)候后執(zhí)行函數(shù)->endMethod()");
- }
- }
//代理角色
public class ProxyRole extends AbsRole{
public RealRole real ;
public ProxyRole(){
}
public void work(){
this.beforeMethod();
if(real == null){
real = new RealRole();
}
real.work();
this.endMethod();
}
public void beforeMethod(){
System.out.println("代理前執(zhí)行函數(shù)->beforeMethod()");
}
public void endMethod(){
System.out.println("代理時(shí)候后執(zhí)行函數(shù)->endMethod()");
}
}
各種角色我們都已經(jīng)定義好了,我們開(kāi)始測(cè)試一下。
- public class Main(){
- public static void main(String[] args){
- AbsRole ar = new ProxyRole();
- ar.work();
- }
- }
public class Main(){
public static void main(String[] args){
AbsRole ar = new ProxyRole();
ar.work();
}
}
二 動(dòng)態(tài)代理
顧名思義,就是不知道到底那個(gè)類需要做代理,在使用的時(shí)候,更具情況臨時(shí)決定。
java動(dòng)態(tài)代理主要是使用java.lang.reflect包中的兩個(gè)類。
1. interface InvocationHandler: 他中定義了一個(gè)方法
- public Object invoke(Object obj,Method method,Object[] obs)
public Object invoke(Object obj,Method method,Object[] obs)
其中第一個(gè)參數(shù) obj 指的是代理類,method是被代理的方法,obs是指被代理的方法的參數(shù)組。此方法由代理類來(lái)實(shí)現(xiàn)。
2. Proxy:該類為動(dòng)態(tài)代理類,主要包括以下內(nèi)容:
- protected Proxy(InvocationHandler h);
-
- static Class getProxyClass(ClassLoader loader,Class[] interfaces);
-
- static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);
protected Proxy(InvocationHandler h);
static Class getProxyClass(ClassLoader loader,Class[] interfaces);
static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);
動(dòng)態(tài)代理其實(shí)是在運(yùn)行時(shí)生成class,所以,我們必須提供一組interface,然后告訴他class已經(jīng)實(shí)現(xiàn)了這些interface,而且在生成Proxy的時(shí)候,必須給他提供一個(gè)handler,讓他來(lái)接管實(shí)際的工作。
現(xiàn)在我們把靜態(tài)代理的例子修改一下:
-
- public interface AbsRole{
- public void work();
- }
//定義抽象角色;
public interface AbsRole{
public void work();
}
接下來(lái)定義真實(shí)角色;
- public class RealRole implements AbsRole{
- public RealRole(){};
-
- public void work(){
- System.out.println("調(diào)用真實(shí)角色方法:RealRole.work()");
- }
- }
public class RealRole implements AbsRole{
public RealRole(){};
public void work(){
System.out.println("調(diào)用真實(shí)角色方法:RealRole.work()");
}
}
然后書寫動(dòng)態(tài)代理編碼
- public class DynamicProxyRole implements InvocationHandler{
- private Object sub;
-
- public DynamicProxyRole(){}
-
- public DynamicProxyRole(Object ob){
- this.sub = ob;
- }
-
- public Object invoke(Object proxy, Method method, Object[] obs) throws Throwable{
- method.invke(sub,obs);
- return null;
- }
- }
public class DynamicProxyRole implements InvocationHandler{
private Object sub;
public DynamicProxyRole(){}
public DynamicProxyRole(Object ob){
this.sub = ob;
}
public Object invoke(Object proxy, Method method, Object[] obs) throws Throwable{
method.invke(sub,obs);
return null;
}
}
代理類已經(jīng)書寫完畢,看看是否能正常運(yùn)行。
- public class Main{
- public static void main(String[] args){
- RealRole rr = new RealRole();
- InvocationHandler dynamicProxy = new DynamicProxyRole(rr);
- Class<?> cls = rr.getClass();
-
- AbsRole r = (AbsRole)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),DynamicProxyRole);
- r.work();
- }
- }
public class Main{
public static void main(String[] args){
RealRole rr = new RealRole();
InvocationHandler dynamicProxy = new DynamicProxyRole(rr);
Class<?> cls = rr.getClass();
AbsRole r = (AbsRole)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),DynamicProxyRole);
r.work();
}
}
調(diào)試成功,動(dòng)態(tài)代理功能完成。
通過(guò)靜態(tài)代理和動(dòng)態(tài)代理學(xué)習(xí),我們小結(jié)一下:
靜態(tài)代理需要事先確定代理對(duì)象和被代理對(duì)象,他們要一起繼承或者是實(shí)現(xiàn)相同的抽象類。動(dòng)態(tài)代理可以在使用的時(shí)候傳入真實(shí)對(duì)象,得到代理。動(dòng)態(tài)代理還是主要依靠java本身的語(yǔ)言特性,實(shí)現(xiàn)代理,更加方便