代理模式一般分為兩種,即靜態(tài)代理和動(dòng)態(tài)代理,靜態(tài)代理限制比較嚴(yán)格,代理類(lèi)和委托類(lèi)必須實(shí)現(xiàn)相同的接口;而動(dòng)態(tài)代理則更加靈活,除了jdk的動(dòng)態(tài)代理,其他的代理方式,如cglib和javassist則沒(méi)有此限制。Hibernate框架加載用戶信息時(shí)有用到cglib動(dòng)態(tài)代理模式,只有在真正查詢用戶實(shí)體信息(如姓名)時(shí),才去數(shù)據(jù)庫(kù)查詢;獲取用戶實(shí)體時(shí),返回的其實(shí)是真實(shí)實(shí)體的一個(gè)子類(lèi)代理而已。
靜態(tài)代理

一般來(lái)講,代理模式可以用在延遲加載,有效提升系統(tǒng)的啟動(dòng)速度。
動(dòng)態(tài)代理

JDK動(dòng)態(tài)代理
jdk動(dòng)態(tài)代理主要原理與靜態(tài)代理基本一致,不過(guò)更加靈活,一般涉及到的核心接口或類(lèi)為InvocationHandler和Proxy,使用方式及實(shí)現(xiàn)原理在參考1中有較為詳細(xì)的解釋。
特別是為什么代理類(lèi)會(huì)執(zhí)行方法時(shí)會(huì)調(diào)用處理分發(fā)器** InvocationHandler的invoke方法的分析特別到位。**
cglib動(dòng)態(tài)代理
cglib動(dòng)態(tài)代理,不用限制代理類(lèi)和委托類(lèi)實(shí)現(xiàn)相同的接口,它的基本使用在參考2中有詳細(xì)的說(shuō)明。
核心示例代碼如下:
//cglib生成動(dòng)態(tài)代理
Enhancer enhancer = new Enhancer();
enhancer.setCallback(new CgLibDBQueryInterceptor()); //指定切入器,一個(gè)實(shí)現(xiàn)MethodInterceptor接口的類(lèi)
enhancer.setInterfaces(new Class[]{IDBQuery.class}); //指定實(shí)現(xiàn)的接口
//enhancer.setSuperclass();指定實(shí)現(xiàn)的父類(lèi)
//生成代理類(lèi)的實(shí)例(沒(méi)有接口限制,此處只不過(guò)恰好是接口而已,如果是普通類(lèi),則代理類(lèi)實(shí)質(zhì)上是普通類(lèi)的子類(lèi))
IDBQuery cglibProxy = (IDBQuery) enhancer.create(); //生成代理類(lèi)實(shí)例
參考
1 Java JDK 動(dòng)態(tài)代理(AOP)使用及實(shí)現(xiàn)原理分析
2 AOP的底層實(shí)現(xiàn)-CGLIB動(dòng)態(tài)代理和JDK動(dòng)態(tài)代理
3 Java動(dòng)態(tài)代理機(jī)制詳解