Java面試基礎篇——第十五篇:代理模式

##什麼是代理? 經過代理控制對象的訪問,能夠詳細訪問某個對象的方法,在這個方法調用處理,或調用後處理。 ##代理應用場景 安全代理 能夠屏蔽真實角色 遠程代理 遠程調用代理類RMI 延遲加載 先加載輕量級代理類,真正須要在加載真實 ##代理的分類java

  • 靜態代理(靜態定義代理類)
  • 動態代理(動態生成代理類) 如 Jdk自帶動態代理, Cglib, javaassist(字節碼操做庫)

接下來舉個Sam賣房子的例子來看看三種代理模式: 靜態代理,jdk自帶動態代理,cglib動態代理。項目構建基於springboot。 ##靜態代理 賣房接口類spring

public interface House {
    //賣房
    void sale();
}

Sam類實現賣房接口緩存

public class Sam implements House {
    @Override
    public void sale() {
        System.out.println("I'm Sam, I want sale my house !");
    }
}

靜態代理類,幫Sam賣房。安全

public class Proxy implements House {
    private Sam sam;

    public Proxy(Sam sam){
        this.sam = sam;
    }

    @Override
    public void sale() {
        System.out.println("proxy listening sale start");
        sam.sale();
        System.out.println("proxy listening sale end");
    }

    public static void main(String[] args) {
        Sam sam = new Sam();
        Proxy proxy = new Proxy(sam);
        proxy.sale();
    }

}

jdk動態代理

經過反射機制來實現調用賣房方法。須要注意的是要實現InvocationHandler。springboot

/**
 * Jdk 動態代理
 */
public class JDKProxy implements InvocationHandler {

    public Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我是房產中介,使用JDK動態代理監聽");
        Object invoke = method.invoke(target, args);
        System.out.println("監聽完成!");
        return invoke;
    }

    public static void main(String[] args) {
        Sam sam = new Sam();
        JDKProxy jdkProxy = new JDKProxy(sam);
        House house = (House) Proxy.newProxyInstance(sam.getClass().getClassLoader(), sam.getClass().getInterfaces(), jdkProxy);
        house.sale();

    }
}

cglib動態代理

須要注意的是要實現MethodInterceptor接口。框架

public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib 代理開始監聽你了  ");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("cglib 代理監聽完成了! ");
        return object;
    }

    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        //使用sam框架
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Sam.class);
        enhancer.setCallback(cglibProxy);
		//asm框架生成
        House house = (House) enhancer.create();
        house.sale();
    }
}

cglib 與jdk 動態代理的區別

jdk動態代理是由Java內部的反射機制來實現的,cglib動態代理底層則是藉助asm來實現的。總的來講,反射機制在生成類的過程當中比較高效,而asm在生成類以後的相關執行過程當中比較高效(能夠經過將asm生成的類進行緩存,這樣解決asm生成類過程低效問題)。 還有一點必須注意:jdk動態代理的應用前提,必須是目標類基於統一的接口。若是沒有上述前提,jdk動態代理不能應用。ide

注:asm其實就是java字節碼控制.this

相關文章
相關標籤/搜索