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

靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼合砂,再對(duì)其編譯青扔。在程序運(yùn)行前,代理類的.class 文件就已經(jīng)存在了翩伪;
動(dòng)態(tài)代理:在程序運(yùn)行時(shí)微猖,運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。

JDK 的動(dòng)態(tài)代理創(chuàng)建機(jī)制—- 通過(guò)接口

使用 JDK 實(shí)現(xiàn)動(dòng)態(tài)代理缘屹,JDK 的動(dòng)態(tài)代理只能對(duì)實(shí)現(xiàn)了接口的類進(jìn)行代理, 被代理的對(duì)象必須要實(shí)現(xiàn)接口凛剥。看下面的案例轻姿。

public interface IPerson {
 void eat();
}
public class Person implements IPerson {
  @Override 
  public void eat() { 
    System.out.println("人要吃飯!!"); 
  }
}
public class PersonInvocationHandler implements InvocationHandler {                
  private Person person;

  public PersonInvocationHandler(Person person) {
    this.person = person;
  } 
  @Override 
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    System.out.println("人吃飯之前要洗手....."); 
    Object invoke = method.invoke(person, args); 
    System.out.println("人吃飯之后要洗碗..."); // 這里可以沒(méi)有返回值, 具體看方法是否需要返回值. 
    return invoke;
  }
}
public class JDKPorxy { 
  public static void main(String[] args) { 
    Person p = new Person(); // 這里創(chuàng)建一個(gè)動(dòng)態(tài)代理類. 人要吃飯之前要 洗手, 吃飯之后還有洗碗. 
    Object o = Proxy.newProxyInstance(p.getClass().getClassLoader(), 
      p.getClass().getInterfaces(), 
      new PersonInvocationHandler(p)); // 必須使用接口 
    IPerson person = (IPerson) o; 
    person.eat(); //end main 
  }
}

output:

人吃飯之前要洗手.....
人要吃飯 !! 
人吃飯之后要洗碗...

cglib 生成動(dòng)態(tài)代理類的機(jī)制—- 通過(guò)類繼承

JDK 中提供的生成動(dòng)態(tài)代理類的機(jī)制有個(gè)鮮明的特點(diǎn)是: 某個(gè)類必須有實(shí)現(xiàn)的接口犁珠,而生成的代理類也只能代理某個(gè)類接口定義的方法逻炊,比如:如果上面例子的 ElectricCar 實(shí)現(xiàn)了繼承自兩個(gè)接口的方法外,另外實(shí)現(xiàn)了方法 bee() , 則在產(chǎn)生的動(dòng)態(tài)代理類中不會(huì)有這個(gè)方法了犁享!更極端的情況是:如果某個(gè)類沒(méi)有實(shí)現(xiàn)接口余素,那么這個(gè)類就不能同 JDK 產(chǎn)生動(dòng)態(tài)代理了!幸好我們有 cglib炊昆〗暗酰“CGLIB(Code Generation Library),是一個(gè)強(qiáng)大的凤巨,高性能视乐,高質(zhì)量的 Code 生成類庫(kù),它可以在運(yùn)行期擴(kuò)展 Java 類與實(shí)現(xiàn) Java 接口磅甩〈读郑”

public class User { 
  public void eat() { 
    System.out.println("人要吃飯!!"); 
  }
}

實(shí)現(xiàn)方法的攔截器

public class CGlibInterceptor implements MethodInterceptor {
  @Override
  public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy)
   throws Throwable {
    System.out.println("人吃飯之前要洗手.....");
    Object invoke = proxy.invokeSuper(obj, args); 
    System.out.println("人吃飯之后要洗碗..."); // 這里可以沒(méi)有返回值, 具體看方法是否需要返回值. 
    return invoke;
  }
}
public class CGlibProxy { 

  public static void main(String[] args) {
    User user = new User(); 
    //cglib 中加強(qiáng)器,用來(lái)創(chuàng)建動(dòng)態(tài)代理  
    Enhancer enhancer = new Enhancer();
    // 設(shè)置要?jiǎng)?chuàng)建動(dòng)態(tài)代理的類 
    enhancer.setSuperclass(user.getClass()); 
    // 設(shè)置回調(diào)(方法攔截器)卷要,這里相當(dāng)于是對(duì)于代理類上所有方法的調(diào)用渣聚,都會(huì)調(diào)用 CallBack,而 Callback 則需要實(shí)行 intercept() 方法進(jìn)行攔截 
    enhancer.setCallback(new CGlibInterceptor()); 
    User u = (User) enhancer.create();
    u.eat(); 
    //end main 
  }
}

output:

人吃飯之前要洗手.....
人要吃飯 !! 
人吃飯之后要洗碗...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末僧叉,一起剝皮案震驚了整個(gè)濱河市奕枝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓶堕,老刑警劉巖隘道,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異郎笆,居然都是意外死亡谭梗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門宛蚓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)激捏,“玉大人,你說(shuō)我怎么就攤上這事凄吏≡毒耍” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵痕钢,是天一觀的道長(zhǎng)图柏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)任连,這世上最難降的妖魔是什么蚤吹? 我笑而不...
    開(kāi)封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮随抠,結(jié)果婚禮上距辆,老公的妹妹穿的比我還像新娘余佃。我一直安慰自己,他們只是感情好跨算,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布爆土。 她就那樣靜靜地躺著,像睡著了一般诸蚕。 火紅的嫁衣襯著肌膚如雪步势。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天背犯,我揣著相機(jī)與錄音坏瘩,去河邊找鬼。 笑死漠魏,一個(gè)胖子當(dāng)著我的面吹牛倔矾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柱锹,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼哪自,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了禁熏?” 一聲冷哼從身側(cè)響起壤巷,我...
    開(kāi)封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞧毙,沒(méi)想到半個(gè)月后胧华,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宙彪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年矩动,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片释漆。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悲没,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灵汪,到底是詐尸還是另有隱情,我是刑警寧澤柑潦,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布享言,位于F島的核電站,受9級(jí)特大地震影響渗鬼,放射性物質(zhì)發(fā)生泄漏览露。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一譬胎、第九天 我趴在偏房一處隱蔽的房頂上張望差牛。 院中可真熱鬧命锄,春花似錦、人聲如沸偏化。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)侦讨。三九已至驶冒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間韵卤,已是汗流浹背骗污。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沈条,地道東北人需忿。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蜡歹,于是被迫代替她去往敵國(guó)和親屋厘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容