JAVA動態代理

代理的分類

代理分爲靜態和動態代理。
靜態代理:硬編碼實現的代理類,在程序被編譯成.class文件時代理類就已經存在。
動態代理:代理類在運行時產生,運用jdk的反射機制動態建立而成。java

靜態代理

靜態代理能夠經過組合的方式來實現,下面看具體的demo實現:函數

public class ProxyTest {

    @Test
    public void proxyMethodTest() {
       
        StaticProxy staticProxy = new StaticProxy(new ClientObject());
        System.out.println(staticProxy.get());
    }
}

interface ClientObjectInterface {
    public String get ();
}

class ClientObject implements ClientObjectInterface {
    public String get () {
        return "hi";
    }
}

class StaticProxy implements ClientObjectInterface {
    ClientObject clientObject;

    public StaticProxy(ClientObject clientObject) {
        this.clientObject = clientObject;
    }

    public String get() {
        return "proxy " + clientObject.get();
    }
}

運行結果:
proxy hithis

當咱們在使用的過程當中發現ClientObject這個類隨着業務需求的變化已經變得不夠用了,這是咱們該怎麼辦?保持着對修改關閉,擴展開放的原則,咱們能夠經過上面那種靜態代理的方式來實現業務需求的變化,固然下面還有一種比較靈活的動態代理的方式來處理上面這種case。編碼

動態代理

動態代理又能夠分爲jdk庫提供的和cglib庫提供,這裏咱們主要講講jdk提供的動態代理。jdk代理對象是經過java.lang.reflect.Proxy#newProxyInstance來進行建立的。代理

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

loader:被代理對象的classloader。
interfaces:被代理對象實現的接口。
h:invocation handler,用於分派執行代理方法。code

下面看下具體的代理實現demo:對象

public class ProxyTest {

    @Test
    public void proxyMethodTest() {
        ClientObject clientObject = new ClientObject();
        ClientObjectInterface object = (ClientObjectInterface) Proxy.newProxyInstance(
            clientObject.getClass().getClassLoader(), clientObject.getClass().getInterfaces(),
            new ObjectProxy());
        System.out.println(object.get());
    }

}

interface ClientObjectInterface {
    public String get ();
}

class ClientObject implements ClientObjectInterface {
    public String get () {
        return "hi";
    }
}


class ObjectProxy implements InvocationHandler {

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("methodName: " + method.getName());
        return "no hi";
    }
}

運行結果:
methodName: get
no hi接口

固然能夠在代理對象裏面作不少事情,本demo只是簡單的替換了被代理對象的函數體。ssl

使用場景

代理的使用場景主要集中在,某一業務須要委託代理類集中處理某一業務而後再執行具體的實現類的業務邏輯。get

相關文章
相關標籤/搜索