【问题标题】:Groovy - How to replace methods of existing java classesGroovy - 如何替换现有 java 类的方法
【发布时间】:2012-02-09 03:35:41
【问题描述】:

如何替换现有 java 类的方法(在我的例子中为GrailsDataBinder)。 我读到java类的方法调用不通过invokeMethod,因此它不起作用,但我认为会有一些解决方案。

我刚试过这个

GrailsDataBinder.metaClass.static.createBinder = {Object target, String objectName ->   
  throw new RuntimeException() 
} 

还有这个

GrailsDataBinder.class.metaClass.static.createBinder = {Object target, String 
  objectName -> throw new RuntimeException() 
} 

但这似乎并没有取代方法,因为我的闭包没有被调用,而是执行了原始方法。

更新

我刚刚发现,如果我从测试类本身调用 createBinder,就会执行闭包 - 所以它可以工作并且方法被替换

void testDataBinder() {
    GrailsDataBinder.createBinder(null, null)
}

但是当从 DataBindingUtils 调用时,它总是执行原始方法(DataBindingUtils 也是一个 java 类)

以下是调用该方法的 DataBindingUtils 中的代码。

binder = GrailsDataBinder.createBinder(object, object.getClass().getName());

注意:之前有人问过一些类似的问题,但没有一个对我有用。

【问题讨论】:

  • 对 DataBindingUtils 的调用是从 Groovy 调用的吗? Groovy 运行时需要获取元类更改。如果您正在将 Groovy 集成到 Java 中并且调用来自 Java,那么它不会看到已修补的更改。
  • 是的,对 DataBindingUtils 的调用是通过 BindDynamicMethod 进行的,而 BindDynamicMethod 又从一个 groovy 类调用。我也尝试过直接从 grails 单元测试用例调用 DataBindingUtils。

标签: grails groovy


【解决方案1】:

看到 Groovy 的强大功能后,这令人失望。然而,正如您已经知道的那样,Groovy 中提供的许多很酷的元类等功能根本无法在 Java 类上正常工作。

如果您试图覆盖、存根或模拟 Java 类上的内容以进行单元测试等,我建议您研究一下 Spock,因为它使用的“魔法”实际上也适用于 Java 类。

如果您出于其他原因尝试覆盖方法,您应该尝试使用 Groovy 类扩展 Java 类或使用 Groovy 类“包装”Java 类,以便在外部类调用您的类时获得所需的元类功能方法。不幸的是,这仍然不允许您拦截 Java 类对其自身进行的调用。

【讨论】:

    猜你喜欢
    • 2012-05-16
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 2012-05-25
    • 2011-02-19
    • 2013-07-26
    相关资源
    最近更新 更多