自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

代理模式之Java動態(tài)代理

開發(fā) 后端
本篇文章介紹了代理模式之Java動態(tài)代理,希望對大家有所幫助。

1. Overview

Java在java.lang.reflect包下,定義了自己的代理。利用這個包下的類,我們可以在運(yùn)行時動態(tài)地創(chuàng)建一個代理類,實(shí)現(xiàn)一個或多個接口。并將方法的調(diào)用轉(zhuǎn)發(fā)到你所指定的類。因?yàn)閷?shí)際代理是在運(yùn)行時創(chuàng)建的,所以稱為:動態(tài)代理。

 

 

Proxy:完全由java產(chǎn)生的,而且實(shí)現(xiàn)了完整的subject接口。

InvocationHandler:Proxy上的任何方法調(diào)用都會被傳入此類,InvocationHandler控制對RealSubject的訪問。

因?yàn)镴ava已經(jīng)幫助我們創(chuàng)建了Proxy類,我們需要有辦法告訴Proxy類你要做什么,我們不能像以前一樣把代碼寫入到Proxy類中,因?yàn)镻roxy類不是我們實(shí)現(xiàn)的。那么我們應(yīng)該放在哪里?放在InvocationHandler類中,InvocationHandler類是響應(yīng)代理的任何調(diào)用。我們可以吧InvocationHandler想成是代理收到方法調(diào)用后,請求做實(shí)際工作的對象。

2. java.lang.reflect.InvocationHandler

被代理實(shí)例所實(shí)現(xiàn)的一個接口,內(nèi)部只有一個invoke()方法,簽名如下;

Java代碼

  1. public Object invoke(Object proxy, Method method, Object[] args)   

 

當(dāng)代理的方法被調(diào)用的時候,代理就會把這個調(diào)用轉(zhuǎn)發(fā)給InvocationHandler,也就會調(diào)用它的invoke()方法。

3. java.lang.reflect.Proxy

提供用于創(chuàng)建動態(tài)代理類和實(shí)例的靜態(tài)方法,它還是由這些方法創(chuàng)建的所有動態(tài)代理類的超類,我們經(jīng)常使用的靜態(tài)方式是:

Java代碼

  1. newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)  

 

4. 示例:

情形:自己可以查看修改姓名性別,但是不能修改rate。他人可以查看姓名,性別以及修改rate,但是不能修改姓名性別。

4.1 定義一個接口:

Java代碼

  1. public interface Person {     
  2.          
  3.     String getName();     
  4.          
  5.     String getGender();     
  6.          
  7.     void setName(String name);     
  8.          
  9.     void setGender(String gender);     
  10.          
  11.     void setRate(int rate);     
  12.          
  13.     int getRate();     
  14. }   

 

4.2 定義實(shí)現(xiàn)Person接口類

Java代碼

  1. public class PersonImpl implements Person {     
  2. String name;     
  3.     
  4. String gender;     
  5.     
  6. String interests;     
  7.     
  8. int rate;     
  9.     
  10. public String getName() {     
  11.     return name;     
  12. }     
  13.     
  14. public void setName(String name) {     
  15.     this.name = name;     
  16. }     
  17.     
  18. public String getGender() {     
  19.     return gender;     
  20. }     
  21.     
  22. public void setGender(String gender) {     
  23.     this.gender = gender;     
  24. }     
  25.     
  26. public String getInterests() {     
  27.     return interests;     
  28. }     
  29.     
  30. public void setInterests(String interests) {     
  31.     this.interests = interests;     
  32. }     
  33.     
  34. public int getRate() {     
  35.     return rate;     
  36. }     
  37.     
  38. public void setRate(int rate) {     
  39.     this.rate = rate;     
  40. }   

 

4.3 定義OwnerInvocationHandler類,表示如果為本人,則可以進(jìn)行修改查看姓名性別。

Java代碼

  1. public class OwnerInvocationHandler implements InvocationHandler{     
  2.          
  3.     private Person personBean;     
  4.          
  5.     public OwnerInvocationHandler(Person personBean){     
  6.         this.personBean = personBean;     
  7.     }     
  8.          
  9.     @Override    
  10.     public Object invoke(Object proxy, Method method, Object[] args)     
  11.             throws IllegalAccessException {     
  12.              
  13.         try {     
  14.             if(method.getName().startsWith("get")){//如果方法名為get,就調(diào)用person類內(nèi)的get相應(yīng)方法     
  15.     
  16.                 return method.invoke(personBean, args);     
  17.             }else if(method.getName().equals("setRate")){ // 如果方法是setRate,則拋出異常     
  18.                 throw new IllegalAccessException("access deny");     
  19.             }else if(method.getName().startsWith("set")){  //如果為set,就調(diào)用person類內(nèi)的set相應(yīng)方法     
  20.                 return method.invoke(personBean, args);     
  21.             }else {     
  22.                 System.out.println("non method invoke");     
  23.             }     
  24.         } catch (InvocationTargetException e) {     
  25.             e.printStackTrace();     
  26.         }     
  27.         return null;      
  28.              
  29.     }     
  30.          
  31. }    

 

4.4 定義NonInvocationHandler類,表示如果不為本人,則可以進(jìn)行查看姓名性別和修改rate。

Java代碼

  1. public class NonInvocationHandler implements InvocationHandler{     
  2.     //     
  3.     private Person person;     
  4.          
  5.     public NonInvocationHandler(Person person){     
  6.         this.person = person;     
  7.     }     
  8.     
  9.     @Override    
  10.     public Object invoke(Object proxy, Method method, Object[] args)     
  11.             throws Throwable {     
  12.         if(method.getName().startsWith("setRate")){     
  13.             return method.invoke(person, args);     
  14.         }else if (method.getName().startsWith("get")){     
  15.             return method.invoke(person, args);     
  16.         } else {     
  17.             System.out.println("non method invoke");     
  18.             return null;     
  19.         }     
  20.     }     
  21.          
  22. }   

 

4.5 測試類MyDynamicProxy

Java代碼

  1. public class MyDynamicProxy {     
  2.     
  3. public Person getOwnerPersonBeanProxy(Person person){     
  4.     return (Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),      
  5.             person.getClass().getInterfaces(), new OwnerInvocationHandler(person));     
  6. }     
  7.     
  8. public Person getNonPersonBeanProxy(Person person){     
  9.     return (Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),      
  10.             person.getClass().getInterfaces(), new NonInvocationHandler(person));     
  11. }     
  12.     
  13. public static void main(String[] args) {     
  14.     MyDynamicProxy mdp = new MyDynamicProxy();     
  15.     mdp.test();     
  16.          
  17. }     
  18.     
  19. public void test(){     
  20.                 //     
  21.     Person person = getPersonBeanFromDB1();     
  22.     Person personProxy = getOwnerPersonBeanProxy(person);     
  23.     System.out.println(personProxy.getName());      
  24.     try {     
  25.         personProxy.setRate(2);     
  26.     } catch (Exception e) {     
  27.         System.out.println("can not setRate");     
  28.     }     
  29.                  //     
  30.     Person person1 = getPersonBeanFromDB1();     
  31.     Person personProxy2 = getNonPersonBeanProxy(person1);     
  32.     System.out.println(personProxy2.getName());     
  33.     personProxy2.setRate(2);     
  34.     System.out.println(personProxy2.getRate());     
  35. }     
  36.     
  37. private Person getPersonBeanFromDB1(){     
  38.     Person pb = new PersonImpl();     
  39.     pb.setName("remy");     
  40.     pb.setGender("girl");     
  41.     pb.setRate(1);     
  42.     return pb;     
  43. }   

 

輸出結(jié)果:

Java代碼

  1. remy     
  2. can not setRate     
  3. remy     
  4. 2 

【編輯推薦】

  1. Java程序開發(fā)中代理技術(shù)的使用方法
  2. 淺談Java中用動態(tài)代理類實(shí)現(xiàn)記憶功能
  3. 探討Java代理模式與反射機(jī)制的實(shí)際應(yīng)用 
責(zé)任編輯:金賀 來源: ITEYE博客
相關(guān)推薦

2011-03-23 10:40:51

java代理模式

2017-10-12 14:56:11

2011-11-17 14:32:45

Java靜態(tài)代理動態(tài)代理

2012-02-29 09:41:14

JavaScript

2012-01-13 15:59:07

2021-06-29 08:54:23

設(shè)計模式代理模式遠(yuǎn)程代理

2012-08-28 10:59:26

JavaJava動態(tài)代理Proxy

2023-12-06 08:23:44

代理模式設(shè)計模式

2010-03-25 08:52:30

PHP設(shè)計模式代理模式

2021-07-06 06:39:22

Java靜態(tài)代理動態(tài)代理

2017-05-11 21:30:01

Android動態(tài)代理ServiceHook

2015-09-22 11:09:47

Java 8動態(tài)代理

2021-09-08 07:18:30

代理模式對象

2022-09-07 08:25:08

代理模式設(shè)計模式代碼

2015-09-28 15:59:00

Java動態(tài)代理機(jī)制

2023-02-24 07:42:30

Java動態(tài)代理

2015-09-24 08:55:14

Java動態(tài)代理擴(kuò)展

2015-09-24 08:54:36

java動態(tài)代理

2020-12-28 07:47:35

動態(tài)代理AOP

2022-01-26 00:05:00

AOPRPC遠(yuǎn)程調(diào)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號