如何探讨Java代理模式与反射机制的实际应用

技术如何探讨Java代理模式与反射机制的实际应用如何探讨Java代理模式与反射机制的实际应用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java提供了一套

如何探索Java代理模式和反射机制的实际应用,相信很多没有经验的人都不知所措。因此,本文总结了出现问题的原因和解决方法,希望大家可以通过这篇文章来解决这个问题。

Java提供了一种动态执行方法、构造函数、数组操作等的机制。这种机制叫做反射。代理模式是一种为其他对象提供代理来控制对此对象的访问的方法,使我们的目标类和代理类实现相同的接口,并在代理类中调用目标类对象。

反射机制是许多流行的Java框架的基础,包括Spring、Hibernate等。如果我们在Java的代理模式中加入反射机制,就可以实现一个公共的代理类,这样就节省了我们很多精力。

import Java . lang . reflect . invocationtargetexception;import Java . lang . reflect . method;/* * *方法代理类* @ Authorrongxinhua * */public class Method proxy { private class clazz;//对象所属的类privateObjecttarget//目标对象privateMethodmethod//目标方法privateObject[]参数;//参数数组@ represswarnings('未选中')public methodproxy(对象目标,字符串methodname,对象.params) {rebind target (target,methodname,params);//设置目标对象和方法}/* * *重置目标对象和方法* @ Param target * @ Param方法名* @ Param params */publicavitrebindttarget(object target,string

nbsp;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代理模式与反射机制的实际应用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/108889.html

(0)

相关推荐

  • 怎么为机器学习工程设计Python接口

    技术怎么为机器学习工程设计Python接口本篇内容主要讲解“怎么为机器学习工程设计Python接口”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么为机器学习工程设计Pyth

    攻略 2021年11月26日
  • 弯月眉,形容身材好腰细的优美句子

    技术弯月眉,形容身材好腰细的优美句子形容女子腰的句子弯月眉。
    1、看她折纤腰以微步,呈皓腕于轻纱。
    眸含春水清波流盼,头上倭堕髻斜插碧玉龙凤钗。
    香娇玉嫩秀靥艳比花娇,指如削葱根口如含朱丹,一颦一笑动人心魂。
    2、一头长

    生活 2021年10月26日
  • 如何理解mysql的锁机制

    技术如何理解mysql的锁机制本篇文章为大家展示了如何理解mysql的锁机制,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 锁0.1 锁机制当前MySQL已经支持 ISAM, M

    攻略 2021年11月16日
  • jdbc操作mysql的步骤(简述jdbc数据库编程的基本步骤)

    技术怎么使用ScalikeJDBC操作MySQL数据库本篇内容介绍了“怎么使用ScalikeJDBC操作MySQL数据库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处

    攻略 2021年12月22日
  • javascript内存泄漏有哪些原因

    技术javascript内存泄漏有哪些原因本篇内容介绍了“javascript内存泄漏有哪些原因”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔

    攻略 2021年11月20日
  • 合羽欠,《伤寒论》中的发热是发烧吗

    技术合羽欠,《伤寒论》中的发热是发烧吗《伤寒论》中的发热合羽欠,并不完全等同于现代说的发烧。现代的发热具体我们首先来看看什么是现代的发烧:发烧,也称发热,是指致热原直接作用于体温调节中枢、体温中枢功能紊乱或各种原因引起的

    生活 2021年10月21日