設計模式——代理模式

代理模式:對一個對象提供另一個對象,能夠在調用正式對象前進行操做,在以後也能夠進行操做。ide

1:靜態代理this

public interface Shopping {
    void shop();
}
public class ShoppingImpl implements Shopping {
    @Override
    public void shop() {
        System.out.println("我要去買東西!");
    }
}
public class ShoppingProxy implements Shopping {
    private Shopping shopping;
    public ShoppingProxy(Shopping shopping) {
        this.shopping = shopping;
    }

    @Override
    public void shop() {
        System.out.println("準備錢");
        shopping.shop();
        System.out.println("付帳走");
    }
}
public class ProxyTest {

    public static void main(String[] args) {
        Shopping shopping = new ShoppingImpl();
        Shopping shopping1 = new ShoppingProxy(shopping);
        shopping1.shop();
    }
}

靜態代理spa

  優勢:在不修改原類的基礎上,能夠進行功能的修改。代理

  缺點:當我建立一個方法的時候,就須要手動的修改代理類。code

2:動態代理對象

public class DynamicProxy implements InvocationHandler {

    private Shopping shopping;

    public DynamicProxy(Shopping shopping) {
        this.shopping = shopping;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("準備錢");
        Object result = method.invoke(shopping,args);
        System.out.println("付帳走");
        return result;
    }

    public Object newProxyInstance(){
        return Proxy.newProxyInstance(shopping.getClass().getClassLoader(),
                shopping.getClass().getInterfaces(),this);
    }
}
public class ProxyTest {

    public static void main(String[] args) {
        Shopping shopping = new ShoppingImpl();
        DynamicProxy dynamicProxy = new DynamicProxy(shopping);
        shopping = (Shopping)dynamicProxy.newProxyInstance();
        shopping.shop();
    }
}

Proxy.newProxyInstance的三個參數blog

   ClassLoader loader, //制定類的加載器
   Class<?>[] interfaces, //制定目標實現的接口
   InvocationHandler h   //動態處理器,執行目標方法時,會觸發動態處理器

雖然動態代理減小了靜態代理工做量,可是惟一的缺點就是必須依賴接口。

3:CJLIB動態代理
接口

public class CglibProxy implements MethodInterceptor {
    private Object target;

    public Object getInstance(final Object target) {
    this.target = target;
    Enhancer enhancer = new Enhancer();
    //設置enhancer的父類
    enhancer.setSuperclass(this.target.getClass());
    //設置enhancer的回調對象
    enhancer.setCallback(this);
    //建立代理對象
    return enhancer.create();

  }
/** * o:cglib生成的代理對象 * method:被代理對象方法 * objects:方法入參 * methodProxy: 代理方法 */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("準備錢"); Object result = methodProxy.invokeSuper(o,objects); System.out.println("付帳走"); return result; } }
public class ProxyTest {

    public static void main(String[] args) {
        Shopping shopping = new ShoppingImpl();
        CglibProxy cglibProxy = new CglibProxy();
        ShoppingImpl shopping1 = (ShoppingImpl)cglibProxy.getInstance(shopping);
        shopping1.shop();
    }
}

cglib主要是針對類的代理,生成一個子類,覆蓋全部的方法,可是final是不能被代理的get

相關文章
相關標籤/搜索