設計模式(四)---- 代理模式
阿新 • • 發佈:2018-11-13
代理模式(Proxy Pattern)
核心作用:通過代理控制物件的訪問;可以詳細訪問某個類或物件的方法,在呼叫這個方法之前做前置處理,呼叫這個方法之後做後置處理;(AOP的微實現)
核心角色:
(1)抽象角色:定義代理角色和真實角色的公共對外方法;
(2)真實角色:實現抽象角色,定義真實角色所要實現的業務邏輯,供代理角色呼叫;(關注真正的業務邏輯)
(3)代理角色:實現抽象角色,是真實角色的代理,通過真實角色的業務邏輯方法來實現抽象方法並附加自己的操作;將統一的流程控制放到代理角色中處理。
應用場景:
安全代理:遮蔽堆真實角色的直接訪問;
遠端代理:通過代理類處理遠端方法呼叫(RMI);
延時載入:先載入輕量級的代理物件,真正需要時在載入真實物件。
分類:
靜態代理(靜態定義代理類)
動態代理(動態生成代理類)
JDK自帶的動態代理;
java assist 位元組碼操作實現;
CGLIB
ASM(底層使用指令,可維護性較差)
一、靜態代理模式
抽象角色:
public interface Star { void confer(); //面談 void signContract();//籤合同 void bookTicket(); //訂票 void sing(); //唱歌 void collectMoney();//收錢 }
真實角色:
public class RealStar implements Star { @Override public void confer() { System.out.println("RealStar.confer()"); } @Override public void signContract() { System.out.println("RealStar.signContract()"); } @Overridepublic void bookTicket() { System.out.println("RealStar.bookTicket()"); } @Override public void sing() { System.out.println("RealStar.sing(周杰倫)"); } @Override public void collectMoney() { System.out.println("RealStar.collectMoney()"); } }
代理角色:
public class ProxyStar implements Star { private Star star; public ProxyStar(Star star) { this.star = star; } @Override public void confer() { System.out.println("ProxyStar.confer()"); } @Override public void signContract() { System.out.println("ProxyStar.signContract()"); } @Override public void bookTicket() { System.out.println("ProxyStar.bookTicket()"); } @Override public void sing() { star.sing(); } @Override public void collectMoney() { System.out.println("ProxyStar.collectMoney()"); } }
測試程式碼:
public class Test { public static void main(String[] args) { RealStar realStar = new RealStar(); Star star = new ProxyStar(realStar); star.confer(); star.signContract(); star.bookTicket(); star.sing(); // star.collectMoney(); } }
二、動態代理(Dynamic Proxy)
動態代理相比於靜態代理的優點:
抽象角色(介面)中宣告的所有方法都被轉移到呼叫處理器一個集中的方法中,這樣我們可以使用更加靈活統一的處理眾多的方法。
1、JDK自帶的類
(1)動態代理需要的處理
java.lang.reflect.InvocationHandler (處理器介面):可以通過 invoke 方法實現對真實物件的代理訪問;每次通過Proxy生成的代理類物件時都有指定代理器物件。
java.lang.reflect.Proxy : 生成代理類和物件。
(2)程式碼實現:抽象角色、真實角色同上
代理角色:
public class ProxyStar implements InvocationHandler
{
private Star star;
public ProxyStar(Star star)
{
this.star = star;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Object object = null;
System.out.println("籤合同");
System.out.println("定機票");
if("sing".equals(method.getName())) //執行的方法名為sing時, 呼叫真實角色的sing方法
{
object = method.invoke(star, args);
}
System.out.println("最後的方法執行");
return object;
}
}
測試類程式碼:
public class Test
{
public static void main(String[] args)
{
Star realStar = new RealStar();
InvocationHandler invocationHandler = new ProxyStar(realStar);
//生成代理物件
Star proxy = (Star) Proxy.newProxyInstance(
RealStar.class.getClassLoader(), //ClassLoader.getSystemClassLoader(),
RealStar.class.getInterfaces(), //new Class[]{Star.class},
invocationHandler);
//只要呼叫了代理物件的任何一個方法都會進入 InvocationHandler 實現類的 invoke() 方法
proxy.sing();
}
}