代理模式(Spring AOP)

介紹

在代理模式(Proxy Pattern)中,一個類代表另一個類的功能。這種類型的設計模式屬於結構型模式。在代理模式中,我們創建具有現有對象的對象,以便向外提供功能接口

意圖:爲其他對象提供一種代理以控制對這個對象的訪問
主要解決:在直接訪問對象時帶來的問題,比如說:要訪問的對象在遠程的機器上。在面向對象系統中,有些對象由於某些原因(比如對象創建開銷大,或者某些操作需要安全控制,或者需要進程外的範文),直接訪問會給使用者或者系統結構帶來很多麻煩,我們可以在訪問此對象時加上一個對此對象的訪問層。

何時使用:想在訪問一個類時做一些控制

如何解決:增加中間層

在這裏插入圖片描述

靜態代理

在這裏插入圖片描述
抽象角色:一般會使用接口或抽象類來解決
真實角色:被代理的角色
代理角色:代理真實角色,代理真實角色後,我們一般會做一些附屬操作
客戶:訪問代理對象的人

以找中介租房子爲例

租房接口

package GProxy.stactic;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/7/2 0002  14:03
 * 租房
 */
public interface Rent {

    public void rent();
}


房東出租房屋


package GProxy.stactic;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/7/2 0002  14:03
 * 房東
 */
public class Host implements Rent {
    @Override
    public void rent() {
        System.out.println("房東要出租房子");
    }
}


中介

package GProxy.stactic;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/7/2 0002  14:04
    中介角色:
 */
public class Proxy implements Rent {

    //將房東組合進來
   private Host host;


    public Proxy(Host host) {
        this.host = host;
    }


    //看房
    public void seeHouse(){
        System.out.println("中介帶你看房");
    }


    public void fare(){
        System.out.println("收中介非");
    }

    @Override
    public void rent() {
            seeHouse();
            host.rent();
            fare();


    }
}



優缺點

優點

  • 可以使得真實角色的操作更加純粹!不用關注一些公共的業務
  • 公共也就交給代理角色,實現業務的分工
  • 公共業務發生擴展的時候,方便集中管理

動態代理

  • 動態代理和靜態代理角色一樣
  • 動態代理的代理類是動態生成的,不是我們直接寫好的
  • 動態代理分爲兩大類:基於接口的動態代理,基於類的動態代理
    • 基於接口---JDK動態代理
    • 基於類:CGLIB
    • java字節碼實現:javasist

基於JDK實現動態代理

相關的類與接口 Proxy InvocationHandler

Proxy類

//通過這個方法返回被代理的對象
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

InvocationHandler接口

//在InvocationHandler中進行方法的增強
   public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;


JDK動態代理實現房屋租賃

租賃接口

package GProxy.dynamic;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/7/2 0002  14:03
 * 租房
 */
public interface Rent {

    public void rent();
}


package GProxy.dynamic;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/7/2 0002  14:03
 * 房東
 */
public class Host implements Rent {
    @Override
    public void rent() {
        System.out.println("房東要出租房子");
    }
}


增強的對象

package GProxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/7/2 0002  15:53
 */
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的接口
    private Rent rent;

    public ProxyInvocationHandler(Rent rent) {
        this.rent = rent;
    }

    public ProxyInvocationHandler() {
    }

    public Rent getRent() {

        return rent;
    }

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //生成得到的代理類
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                                        rent.getClass().getInterfaces(),
                                            this);
    }

    //處理代理實例,並放回結果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //動態代理的本質:就是使用反射機制實現
        System.out.println("看房子");
        Object result = method.invoke(rent,args);
        return result;
    }



}

客戶端調用


package GProxy.dynamic;

import com.sun.org.apache.regexp.internal.RE;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/7/2 0002  15:57
 */
public class Client {
    public static void main(String[] args) {
        //真實角色
        Host host = new Host();
        //代理角色
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();

        //通過調用程序處理角色來處理我們要調用的街路口對象
        proxyInvocationHandler.setRent(host);

        Rent proxy = (Rent)proxyInvocationHandler.getProxy();//這裏的proxy就是通過動態代理生成的,我們並沒有寫

        proxy.rent();
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章