靜態(tài)代理、動(dòng)態(tài)代理

代理分為靜態(tài)代理和動(dòng)態(tài)代理

? ?按照代理創(chuàng)建的時(shí)期,可以分為靜態(tài)代理和動(dòng)態(tài)代理:

? ? (1) 靜態(tài)代理:由程序員或者自動(dòng)生成工具生成代理類,然后進(jìn)行代理類的編譯和運(yùn)行。在代理類、委托類運(yùn)行之前,代理類已經(jīng)以.class的格式存在。

? ? (2)動(dòng)態(tài)代理:在程序運(yùn)行時(shí),由反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。

? ? (3)JDK的動(dòng)態(tài)代理機(jī)制只能代理實(shí)現(xiàn)了接口的類,而不能實(shí)現(xiàn)接口的類就不能實(shí)現(xiàn)JDK的動(dòng)態(tài)代理,cglib是針對(duì)類來實(shí)現(xiàn)代理的,他的原理是對(duì)指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對(duì)final修飾的類進(jìn)行代理。


代理方式實(shí)現(xiàn)優(yōu)點(diǎn)缺點(diǎn)特點(diǎn)

JDK靜態(tài)代理代理類與委托類實(shí)現(xiàn)同一接口,并且在代理類中需要硬編碼接口實(shí)現(xiàn)簡單,容易理解代理類需要硬編碼接口,在實(shí)際應(yīng)用中可能會(huì)導(dǎo)致重復(fù)編碼,浪費(fèi)存儲(chǔ)空間并且效率很低好像沒啥特點(diǎn)

JDK動(dòng)態(tài)代理代理類與委托類實(shí)現(xiàn)同一接口,主要是通過代理類實(shí)現(xiàn)InvocationHandler并重寫invoke方法來進(jìn)行動(dòng)態(tài)代理的,在invoke方法中將對(duì)方法進(jìn)行增強(qiáng)處理不需要硬編碼接口,代碼復(fù)用率高只能夠代理實(shí)現(xiàn)了接口的委托類底層使用反射機(jī)制進(jìn)行方法的調(diào)用

CGLIB動(dòng)態(tài)代理代理類將委托類作為自己的父類并為其中的非final委托方法創(chuàng)建兩個(gè)方法,一個(gè)是與委托方法簽名相同的方法,它在方法中會(huì)通過super調(diào)用委托方法;另一個(gè)是代理類獨(dú)有的方法。在代理方法中,它會(huì)判斷是否存在實(shí)現(xiàn)了MethodInterceptor接口的對(duì)象,若存在則將調(diào)用intercept方法對(duì)委托方法進(jìn)行代理可以在運(yùn)行時(shí)對(duì)類或者是接口進(jìn)行增強(qiáng)操作,且委托類無需實(shí)現(xiàn)接口不能對(duì)final類以及final方法進(jìn)行代理底層將方法全部存入一個(gè)數(shù)組中,通過數(shù)組索引直接進(jìn)行方法調(diào)用



JDK動(dòng)態(tài)代理

package proxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

/**

* @author chexingyou

* @date 2013-6-6

*/

interface Dao {

void show();

void say();

}

interface Dao2 {

void say();

}

class Imp implements Dao, Dao2 {

public void show() {

System.out.println("do show");

}

public void say() {

System.out.println("do say");

}

}

class Handler implements InvocationHandler {

private Object obj;

public Handler(Object obj) {

this.obj = obj;

}

public static Object create(Object obj) {

return Proxy.newProxyInstance(Imp.class.getClassLoader(), Imp.class.getInterfaces(),

new Handler(obj));

}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("before " + method.getName());

Object ret = method.invoke(obj, args);

System.out.println("after " + method.getName());

return ret;

}

}

public class Test {

public static void main(String[] args) {

Dao imp = new Imp();

Dao proxy = (Dao) Handler.create(imp);

proxy.show();

proxy.say();

Dao2 proxy2 = (Dao2) Handler.create(imp);

proxy2.say();

}

}




package cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

/**

* @author chexingyou

* @date 2013-6-7

*/

class Imp {

public void say() {

System.out.println("say()");

}

}

class CglibProxy implements MethodInterceptor {

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)

throws Throwable {

System.out.println("do before");

Object ret = proxy.invokeSuper(obj, args);

System.out.println("do after");

return ret;

}

public Object getProxy(Class<?> clazz) {

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(clazz);

enhancer.setCallback(this);

return enhancer.create();

}

}

public class Test {

public static void main(String[] args) {

CglibProxy proxy = new CglibProxy();

Imp imp = (Imp) proxy.getProxy(Imp.class);

imp.say();

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容