1. 程式人生 > >代理模式之JDK的動態代理

代理模式之JDK的動態代理

      JDK的動態代理比較簡單,是內建在JDK中的,不需要引入第三方jar包,但相對其他代理它的功能就比較弱了。

      下面就以demo為例來學習它。分為延遲載入demo和安全作用的demo

       延遲載入demo

       主題介面: 定義代理類和真實主題的公共對外方法

/**
 * 主題介面
 */
public interface IDBQuery {
    String request();
}

     真實主題:

是實現真正業務邏輯的類,此次假設它是一個重量級物件

public class DBQuery implements IDBQuery {
    public DBQuery() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("真實被建立");
    }
    @Override
    public String request() {
        return "我是真實的";
    }
}

代理類:用來代理和封裝真實主題,代理真實主題的位置,加快系統啟動速度

/**
 * 代理角色
 */
public class DBQueryDelayProxy implements InvocationHandler {
    private IDBQuery real = null;

    public DBQueryDelayProxy() {
        System.out.println("代理被建立");
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(real == null) {
            real = new DBQuery();
        }
        return real.request();
    }
}

 客戶端:

 @Test
    public void jdkDelayProxyTest() {
        IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[] {IDBQuery.class},
                new DBQueryDelayProxy());
        jdkProxy.request();
    }

      中間層作用demo(安全)

       主題介面:是定義代理類和真實主題的公共對外方法

 

public interface JDKInterface {
    /**
     * 出售房
     */
    void sell();

    /**
     * 和租客碰面
     */
    void contact();

    /**
     * 收費
     */
    void charge();
}

真實主題:是真正實現業務邏輯的類

public class JDKHouseOwner implements JDKInterface {
    @Override
    public void sell() {
        System.out.println("售賣的相關事");
    }

    @Override
    public void contact() {
        System.out.println("碰面");
    }

    @Override
    public void charge() {
        System.out.println("房屋出租價格範圍");
    }
}

 代理類: 用來代理和封裝真實主題,可以起到保護真實主題的作用,也可以做延遲載入。本次以安全作用為例:

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

public class JDKIntermediary implements InvocationHandler {
    private JDKInterface real;
    public JDKIntermediary(JDKInterface real) {
        this.real = real;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(real,args);
        return null;
    }
}

 客戶端:

    @Test
    public void jdkProxyTest() {
        JDKInterface real = new JDKHouseOwner();
        InvocationHandler invocationHandler = new JDKIntermediary(real);
        JDKInterface jdkInterface = (JDKInterface) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[] {JDKInterface.class},
                invocationHandler);
        jdkInterface.sell();
        jdkInterface.contact();
        jdkInterface.charge();
    }

代理類的內部邏輯是用JDKIntermediary決定的。生成代理後,由 Proxy.newProxyInstance()返回一個代理類的例項。

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
loader: the class loader to define the proxy class
interfaces: the list of interfaces for the proxy class to implement
h: the invocation handler to dispatch method invocations to