1. 程式人生 > >Java設計模式----------代理模式

Java設計模式----------代理模式

什麼是代理呢,就好比經紀人和演員的關係,有些事情不用演員做,經紀人就直接動手了,也就是說在不訪問被代理類的情況下去呼叫其相關方法。

Java代理分為靜態代理和動態代理 

靜態代理就是和被代理類實現統一介面,然後呼叫其方法,如果我們在編譯時就知道是代理哪個物件 就可以使用靜態代理

首先建立一個介面Animal

/**
 * @author chunying
 */
public interface Animal {

    void eat();
    void run();
}

然後是實現類Cat

/**
 * @author chunying
 */
//被代理類
public class Cat implements Animal{
    @Override
    public void eat() {
        System.out.println("貓吃魚");
    }

    @Override
    public void run() {
        System.out.println("喵喵叫");
    }
}
靜態代理類
/**
 * @author chunying
 */
public class StaticProxy implements Animal{

    private Animal animal;
    
    public StaticProxy(Animal animal) {
        this.animal = animal;
    }
    
    @Override
    public void eat() {
        animal.eat();
    }

    @Override
    public void run() {
        animal.run();
    }
}

測試

@Test
public void fun3() {
   Cat c = new Cat();
   StaticProxy staticProxy = new StaticProxy(c);
   staticProxy.eat();
   staticProxy.run();
}

最終輸出

貓吃魚 喵喵叫

接下來看動態代理

Animal 和 Cat不變

代理物件需要實現InvocationHandler介面 實現方法invoke

/**
 * @author chunying
 */
public class MyInvocationHandler implements InvocationHandler{

    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(target, args);
        return null;
    }
}

我們在執行被代理類的方法時 最終都是呼叫了這個方法,所以可以在這個類中對方法進行一些擴充套件

測試

@Test
public void fun2() {
    Cat cat = new Cat();
    Class<?>[] interfaces = cat.getClass().getInterfaces();
    MyInvocationHandler myInvocationHandler = new MyInvocationHandler(cat);
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    Animal proxy = (Animal)Proxy.newProxyInstance(classLoader, interfaces, myInvocationHandler);
    proxy.eat();
    proxy.run();
}

最終輸出是一樣的  這裡我們建立了一個代理物件,呼叫了Proxy.newProxyInstance()

這個方法有三個引數,第一個是指定的類載入器,第二個是指明被代理類實現的介面,第三個這是一個方法委託類,我們通過代理呼叫被代理類的方法時,就可以將方法名和方法引數都委託給這個委託類。

所以有了類載入器,實現的方法,代理的物件,這樣執行一個被代理類的方法就很簡單了。