`
student_lp
  • 浏览: 429528 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java反射机制(2)反射应用

阅读更多

       在上一篇详细讲解了反射的实现基础,这主要是反射在java 编程中应用非常广泛。例如我们熟知的struts、spring等框架,以及我们后续还要讲到的IoC(控制反转)、AOP(面向切面变成)等理论,这些都是建立在java反射的基础之上的,所以反射非常重要。

    除了上面提到的这些框架,其实我们自己在编写程序的过程中,也经常会用到反射技术。通过反射,可以解决很多问题,也使得我们的代码更加优雅。下面的章节,就为大家介绍两个应用,分别是:动态代理和工厂设计模式。不过在讲动态代理之前,我们还是有必要先复习一下java类的生命周期。

一、java类的生命周期

      在一个类编译完成之后,下一步就要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载、链接、初始化3个步骤完成,类的装载就是通过类加载器把.class二进制文件装入JVM的方法区,并在堆栈创建描述该类的Class对象,用来封装数据。需要注意的是,同一个类只会被JVM加载一次。链接就是把二进制数据封装成可以运行的状态。

     链接分为校验、准备和解析3个步骤。校验用来确认此二进制文件是否适合当前的JVM;准备就是为静态成员分配内存空间,并设置默认值;解析指的是转换常量池的代码引用为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)。完成之后,类型即可初始化,初始化之后类的对象就可以正常的使用,直到一个对象不再使用之后,将被垃圾回收,释放内存空间。当没有任何引用执行class对象时即会被卸载,结束类的生命周期,所以所讲解的生命周期如下图:

二、动态代理详解

      在java中想要实现动态代理机制,需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持。其中InvocationHandler接口定义如下:

    public interface InvocationHandler{

            public  Object  invoke(Object  proxy,Method  method,Object[]  args)throws Throwable

    }

    在此接口中之定义了一个invoke()方法,此方法中有3个参数,其参数的含义如下:

  •      Object  proxy----被代理的对象;
  •      Method  method---要调用的方法;
  •      Object args[] ----方法调用所需要的参数;

    Proxy类时专门完成代理的操作类,可以通过此类为一个或多个接口动态生成实现类。Proxy类提供了如下的操作方法:

    public  static  Object  newProxyInstance(ClassLoader  loader,Class<?>[]  interfaces,InvocationHandler  h)throws IllegalArgumentException。

    通过newProxyInstance()方法可以动态生成实现类,在此方法中的参数含义如下:

  •     ClassLoader loader----类加载器;
  •     Class<?>[]   interfaces-----得到全部的接口;
  •     InvocationHandler h----得到InvocationHandler接口的子类实例。

注意:类加载器。在Proxy类的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是加载器,在java中主要有以下3种类加载器。

  •     Bootstrap  classLoader-----此加载器采用C++编写,一般开发中是看不到的。
  •     Extension  ClassLoader-----用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类。
  •     AppClassLoader ---加载classpath指定的类,是最常用的一种加载器。

      ①如果要完成动态代理,首先要定义一个InvocationHandler接口的子类,已完成代理的具体操作。实例如下:


       在上面的类中bind()方法中接受被代理对象的真是主体实现,之后复写InvocationHandler接口中的invoke()方法,完成具体的方法调用。

     ②定义接口

     ③实现定义的接口

      以上定义了接口以及它的实现类,这样在操作时直接将真实主题类的对象传入到MyInvocationHandler类的bind()方法中即可。

     ④调用动态代理

   从程序的运行接口来看,和静态代理操作没有什么不同。但是这一般在开发中很少使用到这种动态代理机制,但是在编写一些底层代码或使用一些框架(如Spring)时这种动态代理模式就比较常用了。

三、初探工厂模式编程

       工厂设计模式在实际开发过程中使用的非常多,例如通过简单的工厂设计模式就可以达到解耦的目的。普通的工厂模式,每增加一个子类都需要修改工厂类,这非常麻烦。但是通过反射机制,可以显著的改善工厂类,让其在添加子类时可以不用做任何修改,就可以达到功能的扩充。下面是一个工厂模式的实例:



 上面的工厂类中使用了反射,这样无论添加多少个子类,工厂类都不用进行任何修改。这是一个简单的实例,给大家一个思路。有关java的编程模式,会在后面的章节中具体介绍。请继续关注。

 

 

  • 大小: 19.7 KB
  • 大小: 62.7 KB
  • 大小: 18.3 KB
  • 大小: 25.7 KB
  • 大小: 39.8 KB
  • 大小: 56.5 KB
  • 大小: 44 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics