科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件JRockit JVM对AOP的支持

JRockit JVM对AOP的支持

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

  面向方面编程(Aspect-Oriented Programming,AOP)正在软件社区和企业界中获得强大的发展动力。自从20世纪90年代Xerox引入了AOP之后,AOP经过研究团体、开源社区和企业界的数次推动和革新

作者:中国IT实验室 来源:中国IT实验室 2007年8月24日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
作为更现实的例子,以下代码匹配所有三个EJB业务方法:
// Prepare the pointcut to match
// @Stateless annotated classes business methods
MethodFilter ejbBizMethods = new MethodFilter(
    PUBLIC_NONSTATIC,
    // Method annotation does not matter
    null,
    new ClassFilter(
        // Declaring class, the java.lang.Class
        // for the EJB we are currently manipulating
        ejbClass,
        // no subtypes matching
        false,
        // class annotation
        Stateless.class
    ),
    // EJB methods matching is handled
    // in a UserDefinedFilter below instead
    null,
    // return type does not matter
    null,
    // custom Filter callback
    new UserDefinedFilter() {
        public boolean match(
                       MethodFilter methodFilter,
                       WMember member,
                       WMethod within) {
            return !isEjbLifeCycleMethod(member);
        }
    }
);

好处

  使用JVM编织而不是字节码测试有几个好处。从较高的层面来看,编织作为JVM功能的自然扩展出现,因此在许多方面它不那么具有侵入性,并且为性能、可伸缩性和可用性各方面带来了许多好处。

  关于字节码编织的问题(尤其是在加载时编织的情况下)的详细讨论,请参考本系列的第1部分。以下好处解决了所有这些问题。

  • 不使用字节码测试,增强了可伸缩性

  字节码没有被修改。在JVM内部组件中,仍然采用从字节码到可执行代码的常规编译管道。使用字节码测试时,需要分析字节码指令并用某些中间结构来表示它们,这样才能在测试框架(AOP编织器或基于字节码测试的产品)中操纵它们;而使用JVM编织不需要这么做。

  编织器变得无所不在了。即使用户希望在启动时注册预定,这也不再是必须的。因为根本不需要分析字节码指令来寻找要截取的联结点,所以大大减少了应用程序的启动时间。这也提供了开发真正动态的系统的机会——动态意味着可以在任何时候部署方面和解除方面部署,而又不会由此引起额外的开销或复杂性。

  • 不使用冗余的类型信息记录,降低了内存耗用并且提高了可伸缩性

  因为不再进行字节码测试,因此与对象模型双重记录问题相关的问题就不会出现了。预定API依赖于java.lang.reflect.*模型,而这个模型已经以类似的方式向Java开发人员提供了此信息。

  • 多个代理可以保持一致

  因为所编织的类的字节码没有经过修改,所以不会因为两个不同的代理以不兼容的方式修改字节码(相互隐藏原始程序的属性),而造成冲突。预定的注册次序起到了优先权规则的作用。注意,如果类是可序列化的,那么不会为了在运行时执行所编织的建议而向其添加隐藏结构,所以常规的序列化将得到充分支持。而字节码测试技术通常需要确定序列化能力是否有所保留(例如,serialVersionUID字段的处理)。

  • 支持截取反射式调用

  通过使用JVM级方法调度,所有反射式调用(方法调用或者get或set字段)都可以被匹配,就像它们是常规调用,而且所有注册的动作都将被触发一样。这不需要任何额外的开销,也不涉及特定于实现的细节和复杂性。

未来的发展方向

  尽管JVM编织很有帮助,而且解决了与字节码测试技术相关的可伸缩性和可用性问题,但是仍然必须解决一些缺陷才能使其完美地实现用例,这可能需要采用一些补充方法。

  一些基于字节码测试的产品使用了细粒度更改,当前的JVM AOP API还无法实现这一特性。某些用例处理同步块,因此不同的锁定机制(如:分布式锁定)可以透明地注入常规的应用程序。这样的细粒度动作常常要求对同步块进行有条件执行,甚至完全删除同步块,并使用某个专用锁定API调用来替换它。可以在JVM中解决这样的特定需求,但是实际上不可能找到一个对每种用例都有效的高效解决方案。还有必要提醒一下的是,目前领先的AOP框架还不能将同步块公开为联结点。

  在JVM级别上,无法轻松地实现AspectJ定义的某些细粒度语义。例如,AspectJ支持预初始化、初始化和构造函数执行切点。构造函数执行切点挑选出源代码中出现的构造函数,初始化切点挑选出获得已初始化实例的所有构造函数执行,包括this(...)构造函数委托。JVM难以把握这两者的差异。更具侵入性的代码内联策略可能会出现在哪些地方实际上也可能取决于编译器。

  随着字节码测试逐渐流行起来,新的JVM API的引入肯定会遇到挑战。如果要开发一种同时适应两种JVM(支持新API的JVM,比如JRockit,以及不支持新API的JVM)的产品,那么成本会相当高。这个领域中的规范(如:JSR)可能有助于克服这种困难。

结束语

  字节码测试技术目前已经在不同领域的Java平台上得到广泛使用,从面向方面软件开发到更特定于应用的解决方案(如:应用程序监控、持久性或分布式计算)。随着字节码测试的可用性和透明性的提高,加载时编织和部署时测试将会流行起来。

  遗憾的是,这种技术没有为可伸缩性和可用性需求提供适当的支持。特别是随着这种技术的应用越来越广泛,以及对来自不同产品的不同测试代理的混合使用,这个问题会越来越严重。JVM编织和JVM对AOP的支持(比如在JRockit中所实现的)是解决这个问题的自然方法,可以促进革新和技术发展。JRockit团队所提出的Java API将JVM方法调度内部组件与用户定义的动作联系起来,仅依赖于java.lang.reflect API的预定优雅地填补了以前的鸿沟,并解决了主要的可伸缩性和可用性问题。

  这种新的API要想获得广泛采用,需要对它进行认真的评估,并将它应用于真实的用例,比如AOP或者大型应用程序的运行时自适应。

参考资料

  • JRockit JVM Support For AOP, Part 1(JRockit JVM对AOP的支持,第1部分),作者Jonas Bonér、Joakim Dahlstedt和Alexandre Vasseur(dev2dev,2005年8月)——即本系列的第1篇文章。
  • JRockit Technology Center——第一个具有AOP支持的企业级JVM的站点。
  • 新闻组:jrockit.developer.interest.aop。
  • AspectWerkz——普通Java AOP框架。
  • AspectJ——用Java实现AOP的事实标准。

  Quick Start Guide to Enterprise AOP with Aspectwerkz 2.0,作者David Teare(dev2dev,2005年4月)。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章