Java動態代理

Java動態代理java

什麼是動態代理?設計模式

一、A接口有C方法,類B實現A接口,本來應該是執行B類中的C方法,可如今不這樣作。ide

二、如今聲明產生B類的代理類‘B’,由它來冒充B類的「兄弟」並「實現」A接口。測試

三、對外界來講‘B’應該也有C方法,可當真正的調用它時,它會執行與它關聯InvocationHandler的invoke()方法,在這個方法裏面你能夠作不少事情。this

 

 

動態代理:spa

代理模式是經常使用的java設計模式,它的特徵是:設計

》代理類與委託類有一樣的接口代理

》代理類主要負責爲委託類預處理消息、過濾消息、把消息轉發給委託類,以及時候處理消息等code

》代理類與委託類之間一般會存在關聯關係,一個代理類的對象與一個委託類的對象關聯。對象

》代理類的對象自己並不真正實現服務,而是經過調用委託類的對象的相關方法,來提供特定的服務。

 

JDK動態代理中包含一個類和一個接口:
InvocationHandler接口:
public interface InvactionHandler{
        
      public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;  

}
參數說明:
Object proxy:指被代理的對象
Method method:要調用的方法
Object[] args:方法調用時所須要的參數

  

Proxy類:
Proxy類是專門完成代理的操做類,能夠經過此類爲一個或多個接口動態地生成實現類,此類提供以下操做的方法:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
參數說明:
ClassLoader loader:類加載器
Class<?>[] interfaces:獲得所有的接口
InvocationHandler h:獲得InvocationHandler接口的子類實例

  

實例:

public interface Dinner {
    public void haveDinner();
}

//被代理類
public class MyDinner implements  Dinner{
    @Override
    public void haveDinner() {
        System.out.println("媽媽作飯真好吃");
    }
}

//代理類
public class MyDinnerProxy implements InvocationHandler {
    private Object obj;
    //綁定被代理類對象,返回代理類對象
    public Object bind(Object obj){
        this.obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    }
    private void before(){
        System.out.println("吃飯前洗手");
    }
    private void after(){
        System.out.println("吃飯後刷碗");
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        after();
        Object retrunVal = method.invoke(obj,args);
        before();
        return retrunVal;
    }
}

//測試類
    public static void main(String[] args){

        Dinner hd = new MyDinner();//能夠調用被代理類重寫的方法
        MyDinnerProxy mdp = new MyDinnerProxy();建立一個這個類的對象
        //返回一個代理類對象,向上轉型,調用重寫的方法,也就是invoke()方法
        hd = (Dinner) mdp.bind(hd);
        hd.haveDinner();
    }
相關文章
相關標籤/搜索