91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何探討Java代理模式與反射機制的實際應用

發布時間:2021-11-20 18:10:34 來源:億速云 閱讀:178 作者:柒染 欄目:編程語言

如何探討Java代理模式與反射機制的實際應用,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

Java提供了一套機制來動態執行方法和構造方法,以及數組操作等,這套機制就叫反射。而代理模式是為其他對象提供一種代理以控制對這個對象的訪問,讓我們的目標類和代理類實現同一接口,在代理類中調用目標類對象的方法。

反射機制是如今很多Java流行框架的實現基礎,其中包括Spring、Hibernate等。如果我們將反射機制加入到Java的代理模式中,就可以實現一個公共的代理類,省去我們不少功夫。

import java.lang.reflect.InvocationTargetException;     import java.lang.reflect.Method;     /**     * 方法代理類     * @author rongxinhua     *     */    public class MethodProxy {                  private Class clazz;    //對象所屬的類         private Object target;  //目標對象         private Method method;  //目標方法         private Object[] params;    //參數數組                  @SuppressWarnings("unchecked")         public MethodProxy(Object target, String methodName, Object ... params) {             rebindTarget(target, methodName, params);   //設置目標對象與方法         }                  /**         * 重新設置目標對象與方法         * @param target         * @param methodName         * @param params         */        public void rebindTarget(Object target, String methodName, Object ... params) {             this.target = target;             this.clazz = target.getClass();             rebindMethod(methodName, params);   //設置目標方法         }                  /**         * 重新設置目標方法         * @param methodName         * @param params         */        public void rebindMethod(String methodName, Object ...params) {             this.params = params;             int paramLength = params.length;             Class[] paramTypes = new Class[paramLength];             for(int i = 0 ; i < paramLength ; i ++ ) {                 paramTypes[i] = params[i].getClass();             }             try {                 this.method = clazz.getMethod(methodName, paramTypes);             } catch (SecurityException e) {                 e.printStackTrace();             } catch (NoSuchMethodException e) {                 e.printStackTrace();             }         }                  /**         * 動態調用已綁定的方法         */        public void doMethod() {             try {                 this.method.invoke(target, params);             } catch (IllegalArgumentException e) {                 e.printStackTrace();             } catch (IllegalAccessException e) {                 e.printStackTrace();             } catch (InvocationTargetException e) {                 e.printStackTrace();             }         }         }    import java.lang.reflect.InvocationTargetException;  import java.lang.reflect.Method;  /**   * 方法代理類   * @author rongxinhua   *   */  public class MethodProxy {      private Class clazz; //對象所屬的類   private Object target; //目標對象   private Method method; //目標方法   private Object[] params; //參數數組      @SuppressWarnings("unchecked")   public MethodProxy(Object target, String methodName, Object ... params) {    rebindTarget(target, methodName, params); //設置目標對象與方法   }      /**    * 重新設置目標對象與方法    * @param target    * @param methodName    * @param params    */   public void rebindTarget(Object target, String methodName, Object ... params) {    this.target = target;    this.clazz = target.getClass();    rebindMethod(methodName, params); //設置目標方法   }      /**    * 重新設置目標方法    * @param methodName    * @param params    */   public void rebindMethod(String methodName, Object ...params) {    this.params = params;    int paramLength = params.length;    Class[] paramTypes = new Class[paramLength];    for(int i = 0 ; i < paramLength ; i ++ ) {     paramTypes[i] = params[i].getClass();    }    try {     this.method = clazz.getMethod(methodName, paramTypes);    } catch (SecurityException e) {     e.printStackTrace();    } catch (NoSuchMethodException e) {     e.printStackTrace();    }   }      /**    * 動態調用已綁定的方法    */   public void doMethod() {    try {     this.method.invoke(target, params);    } catch (IllegalArgumentException e) {     e.printStackTrace();    } catch (IllegalAccessException e) {     e.printStackTrace();    } catch (InvocationTargetException e) {     e.printStackTrace();    }   }   }   這樣就可以實現動態地調用某個對象的某個方法了,寫個測試代碼如下:   public class Manager {                  public void say() {             System.out.println("Nobody say nothing");         }                  public void love(String boy, String girl) {             System.out.println(boy + " love " + girl);         }              }    public class Manager {      public void say() {    System.out.println("Nobody say nothing");   }      public void love(String boy, String girl) {    System.out.println(boy + " love " + girl);   }     }

我們通過代理類來調用Manager類中的say()和love()方法,測試代碼如下:

Manager man = new Manager();    //目標對象     MethodProxy proxy = new MethodProxy(man, "say");    //方法代理對象     proxy.doMethod();   //調用被代理的方法     proxy.rebindMethod("love", "Tom", "Marry"); //重新綁定方法     proxy.doMethod();   //調用被代理的方法    Manager man = new Manager(); //目標對象  MethodProxy proxy = new MethodProxy(man, "say"); //方法代理對象  proxy.doMethod(); //調用被代理的方法  proxy.rebindMethod("love", "Tom", "Marry"); //重新綁定方法  proxy.doMethod(); //調用被代理的方法

這樣就實現了動態代理調用對象的方法,上面代碼輸出結果就不貼出來了。如果要設置前置通知和后置通知等功能,也很容易實現,只需在“proxy.doMethod()”代碼處的前面和后面設置即行。擴展應用:我們在上面的MethodProxy類中加入以下方法:

/**     * 獲取方法上的注解     * @param anClazz 注解類     * @return     */    public Annotation getAnnotation(Class anClazz) {         return this.method.getAnnotation(anClazz);     }     /**    * 獲取方法上的注解    * @param anClazz 注解類    * @return    */   public Annotation getAnnotation(Class anClazz) {    return this.method.getAnnotation(anClazz);   }

這個方法用來讀取方法上的注解(Annotation),有什么用呢?我們寫一個注解來測試下。

@Retention(RetentionPolicy.RUNTIME)     @Target(ElementType.METHOD)     @interface Low {         int boyAge();          int girlAge();       }    @Retention(RetentionPolicy.RUNTIME)  @Target(ElementType.METHOD)  @interface Low {   int boyAge();    int girlAge();   }

我們要引進Annotation相關的類:

import java.lang.annotation.Annotation;     import java.lang.annotation.ElementType;     import java.lang.annotation.Retention;     import java.lang.annotation.RetentionPolicy;     import java.lang.annotation.Target;    import java.lang.annotation.Annotation;  import java.lang.annotation.ElementType;  import java.lang.annotation.Retention;  import java.lang.annotation.RetentionPolicy;  import java.lang.annotation.Target;

我們另外寫一個測試用的業務類:

public class LoveManager {                  @Low(boyAge=12, girlAge=10)         public void beAbleToLove(Person boy, Person girl) {             System.out.println(boy.getName() + " is able to love " + girl.getName());         }              }         public class Person {         private String name;         private int age;         public Person(String name, int age) {             this.name = name;             this.age = age;         }         //getter方法略     }    public class LoveManager {      @Low(boyAge=12, girlAge=10)   public void beAbleToLove(Person boy, Person girl) {    System.out.println(boy.getName() + " is able to love " + girl.getName());   }     }   public class Person {   private String name;   private int age;   public Person(String name, int age) {    this.name = name;    this.age = age;   }   //getter方法略  }

接寫上例中的proxy對象測試代碼:

LoveManager loveManager = new LoveManager();     Person boy = new Person("Tom", 13);     Person girl = new Person("Marry", 10);     proxy.rebindTarget(loveManager, "beAbleToLove", boy, girl); //重新綁定對象和方法     Low low = (Low)proxy.getAnnotation(Low.class);     if(boy.getAge() < low.boyAge()) {         System.out.println(boy.getName() + "還不到法定年齡,不能談戀愛!");     } else if(girl.getAge() < low.girlAge()) {         System.out.println(girl.getName() + "還不到法定年齡,不能談戀愛!");     } else {         proxy.doMethod();     }      LoveManager loveManager = new LoveManager();    Person boy = new Person("Tom", 13);    Person girl = new Person("Marry", 10);    proxy.rebindTarget(loveManager, "beAbleToLove", boy, girl); //重新綁定對象和方法    Low low = (Low)proxy.getAnnotation(Low.class);    if(boy.getAge() < low.boyAge()) {     System.out.println(boy.getName() + "還不到法定年齡,不能談戀愛!");    } else if(girl.getAge() < low.girlAge()) {     System.out.println(girl.getName() + "還不到法定年齡,不能談戀愛!");    } else {     proxy.doMethod();    }

這就實現了,通過Java的反射機制來讀取Annotation的值,并根據Annotation的值,來處理業務數據有效性的判斷,或者面向切面動態地注入對象,或者作日志、攔截器等等。這種用法在所多框架中都常常看到, 我們在開發自己的Java組件時,不妨也采用一下吧!

看完上述內容,你們掌握如何探討Java代理模式與反射機制的實際應用的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巴塘县| 柏乡县| 濮阳市| 莱芜市| 万州区| 霍邱县| 陇南市| 武穴市| 闸北区| 云阳县| 海门市| 通州区| 盐城市| 建宁县| 易门县| 定西市| 宁安市| 临邑县| 全南县| 高州市| 内乡县| 怀化市| 临安市| 金门县| 阿巴嘎旗| 任丘市| 沿河| 田阳县| 石城县| 秦皇岛市| 马龙县| 宜阳县| 永修县| 久治县| 金沙县| 莱州市| 阿瓦提县| 东方市| 舞阳县| 贡觉县| 河西区|