cglib和jdk自帶的動(dòng)態(tài)代理
記得上次的動(dòng)態(tài)代理贩耐,感覺(jué)講的不是很好浆熔,因?yàn)槲衣┝撕脦讉€(gè)重要的點(diǎn)蚓土。而且關(guān)于cglib這個(gè)基于asm框架的代理也沒(méi)講到宏侍。求知切記不要一知半解。
從上次的動(dòng)態(tài)代理展開(kāi)蜀漆,為什么我們?cè)緅dk自帶了動(dòng)態(tài)代理谅河,偏偏又出來(lái)個(gè)cglib這個(gè)額外第三方庫(kù)呢?人家總不可能是傻子吧确丢,造了的輪子再造一遍绷耍。說(shuō)明自帶的動(dòng)態(tài)代理有不足點(diǎn):
委托類必須實(shí)現(xiàn)接口(拿上次的例子來(lái)說(shuō)就是學(xué)生是委托類,DynamicProxy是代理類)
現(xiàn)實(shí)的開(kāi)發(fā)中不可能所有的類都實(shí)現(xiàn)接口吧(好吧雖然這是一個(gè)面向接口鲜侥、面向配置文件編程語(yǔ)言)褂始,所以出現(xiàn)了cglib這個(gè)與眾不同的輪子,它不是基于反射機(jī)制描函,它是基于asm這個(gè)直接能夠修改字節(jié)碼的框架崎苗。我們只要知道一點(diǎn)那就是基于jdk的動(dòng)態(tài)代理他的代理類實(shí)際上是實(shí)現(xiàn)與它相同的接口狐粱,這就意味著你不實(shí)現(xiàn)接口jdk的動(dòng)態(tài)代理是無(wú)法為您提供服務(wù)的
cglib
填完上次的坑,我們來(lái)簡(jiǎn)單看下cglib胆数。我們直接上例子吧
我們?nèi)缟洗文菢酉榷x一個(gè)不實(shí)現(xiàn)Person接口的類Teacher
public class Teacher{
public void eat() {
System.out.println("teacher is eating dinner");
}
public void drink() {
System.out.println("teacher is drinking juice");
}
public void sleep() {
System.out.println("teacher is sleeping");
}
public void WC() {
System.out.println("teacher is WCing");
}
}
再是一個(gè)方法攔截器類
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class TeacherInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("----starting!----");
Object object = proxy.invokeSuper(obj, args);//調(diào)用委托類的原方法
System.out.println("----ending!----");
return object;
}
}
最后的最后是測(cè)試類
import net.sf.cglib.proxy.Enhancer;
public class TestCglib {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Teacher.class);
enhancer.setCallback(new TeacherInterceptor());
Teacher t = (Teacher)enhancer.create();
t.drink();
}
}
具體背后怎么實(shí)現(xiàn)其實(shí)是一種基于索引的方式調(diào)用委托類的具體看狼哥的分析