Java编程的动态性,第5部分: 动态转换类

http://www.bianceng.cn/Programming/Java/201104/25754.htm

 

Java编程的动态性,第5部分: 动态转换类

时间:2011-04-09 IBM Dennis M. Sosnoski

在经过一段时间的休息之后,Dennis Sosnoski 又回来推出了他的 Java 编程的动态性系 列的第 5 部分。您已在前面的文章中看到了如何编写用于转换 Java 类文件以改变代码行为 的程序。在本期中,Dennis将展示如何使用 Javassist 框架,把转换与实际的类加载过程结 合起来,用以进行灵活的“即时”面向方面的特性处理。这种方法允许您决定想要在运行时 改变的内容,并潜地在每次运行程序时做出不同的修改。在整个过程中,您还将更深入地了 解向JVM 中加载类的一般问题。

在第 4 部分“ 用 Javassist 进行类转换”中,您学习了如何使用 Javassist 框架来转 换编译器生成的 Java 类文件,同时写回修改过的类文件。这种类文件转换步骤对于做出持 久变更是很理想的,但是如果想要在每次执行应用程序时做出不同的变更,这种方法就不一 定很方便。对于这种暂时的变更,采用在您实际启动应用程序时起作用的方法要好得多。

JVM 体系结构为我们提供了这样做的便利途径――通过使用 classloader 实现。通过使 用 classloader 挂钩(hook),您可以拦截将类加载到 JVM 中的过程,并在实际加载这些 类之前转换它们。为了说明这个过程是如何工作的,我将首先展示类加载过程的直接拦截, 然后展示 Javassist 如何提供了一种可在您的应用程序中使用的便利捷径。在整个过程中, 我将利用取自本系列以前文章中的代码片断。

加载区域

运行 Java 应用程序的通常方式是作为参数向 JVM 指定主类。这对于标准操作没有什么 问题,但是它没有提供及时拦截类加载过程的任何途径,而这种拦截对大多数程序来说是很 有用的。正如我在第 1 部分“ 类和类装入”中所讨论的,许多类甚至在主类还没有开始执 行之前就已经加载了。要拦截这些类的加载,您需要在程序的执行过程中进行某种程度的重 定向。

幸运的是,模拟 JVM 在运行应用程序的主类时所做的工作是相当容易的。您所需做的就 是使用反射(这是在不得 第 2 部分 中介绍的)来首先找到指定类中的静态 main() 方法, 然后使用预期的命令行参数来调用它。清单 1 提供了完成这个任务的示例代码(为简单起见 ,我省略了导入和异常处理语句):

清单 1. Java 应用程序运行器

public class Run
{
   public static void main(String[] args) {
     if (args.length >= 1) {
       try {

         // load the target class to be run
         Class clas = Run.class.getClassLoader().
           loadClass(args[0]);

         // invoke "main" method of target class
         Class[] ptypes =
           new Class[] { args.getClass() };
         Method main =
           clas.getDeclaredMethod("main", ptypes);
         String[] pargs = new String[args.length-1];
         System.arraycopy(args, 1, pargs, 0, pargs.length);
         main.invoke(null, new Object[] { pargs });

       } catch ...
       }

     } else {
       System.out.println
         ("Usage: Run main-class args...");
     }
   }
}

要使用这个类来运行 Java 应用程序,只需将它指定为 java 命令的目标类,后面跟着应 用程序的主类和想要传递给应用程序的其他任何参数。换句话说,如果用于运行 Java 应用 程序的命令为:

java test.Test arg1 arg2 arg3

您相应地要通过如下命令使用 Run 类来运行应用程序:

java Run test.Test arg1 arg2 arg3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值