設(shè)計(jì)模式之代理模式

代理模式

代理模式就是在不修改原有代碼的情況下,通過代理對象完成一些新增功能(開閉原則)
也就是橫切業(yè)務(wù),面向切面編程

代理模式分類:

  • 靜態(tài)代理
  • 動態(tài)代理

使用場景:

  • SpringAOP底層

1. 靜態(tài)代理
角色分析:

  • 抽象角色:一般使用接口或者抽象類來解決
  • 真實(shí)角色:被代理角色
  • 代理角色:代理真實(shí)角色,一般做一些附屬操作(切入功能)
// 接口
public interface Rent{
    void rent();
}
// 真實(shí)對象
public class Landlord implements Rent{
    public void rent(){
        System.out.println("出租房子");
    }
}
// 代理對象
public class Proxy implements Rent{
    
    private Landlord landlord;
    
    public Proxy(Landlord landlord){
        this.landlord = landlord;
    }
    
    // 中介租房,加了附屬操作
    public void rent(){
        // 前置通知
        lookHouse();
        landlord.rent();
        // 后置通知
        contract();
        fees();
    }
    
    // 代理對象擴(kuò)展方法,看房子
    public void lookHouse(){
        System.out.println("看房子");
    }
    
    // 簽合同
    public void contract(){
        System.out.println("簽合同");
    }
    
    // 中介費(fèi)
    public void fees(){
        System.out.println("簽合同");
    }

}

靜態(tài)代理的缺點(diǎn)就是一個(gè)真實(shí)角色會產(chǎn)生一個(gè)代理角色,所以需要?jiǎng)討B(tài)代理


2. 動態(tài)代理

  • 動態(tài)代理和靜態(tài)代理角色一樣
  • 動態(tài)代理的代理類是動態(tài)生成的,不是直接寫好的
  • 動態(tài)代理分為兩大類:基于接口的動態(tài)代理,基于類的動態(tài)代理
    • 基于接口:JDK動態(tài)代理
    • 基于類:cglib
    • java字節(jié)碼:JAVAssist

相關(guān)類:Proxy、 InvocationHandler

public class ProxyTest implements InvocationHandler{
    
    // 代理對象
    private Object target;
    
    public setTarget(Object target){
        this.target = target;
    }
    
    //生成代理類
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
        target.getClass().getInterfaces(), this)
    }
    
    // 處理代理對象實(shí)例方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        // 切入
        log(method.getName());
        
        // 調(diào)用真實(shí)對象方法, 動態(tài)代理的本質(zhì)是反射(invoke就是反射中的方法調(diào)用)
        Object result = method.invoke(target, args);
        return result;
    }
    
    
    // 當(dāng)需要添加功能時(shí)只需要橫切
    public void log(String name){
        System.out.println("執(zhí)行了"+name+"方法");
    }
    
}

調(diào)試

public class Client{
    public static viod main(String[] args){
        // 真是對象
        Rent rent = new Rent();
        // 代理對象生成類
        ProxyTest proxy = new ProxyTest();
        // 設(shè)置代理的真實(shí)對象
        proxy.setTarget(rent);
        // 獲取代理對象
        Object obj = proxy.getProxy();
        
        // 調(diào)用出租方法
        obj.rent();
    }
}

動態(tài)代理類代理的是一個(gè)接口,一類業(yè)務(wù)

代理模式的好處:

  • 可以使真實(shí)角色的操作更純粹
  • 公共業(yè)務(wù)交給代理實(shí)現(xiàn)業(yè)務(wù)分工
  • 公共業(yè)務(wù)發(fā)生擴(kuò)展方便管理
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容