【问题标题】:MetaClass not intercepting protected methodMetaClass 不拦截受保护的方法
【发布时间】:2014-05-20 23:47:41
【问题描述】:

我正在测试 groovy.sql.Sql 元类中的运行时更改,修改 createConnection 方法。我的目标是在请求某些连接时始终调用进程。

更改受保护的方法是否有限制?我可以看到我的更改没有效果,如果我记录 invokeMethod(),则只会打印公共方法。

也许我的方法不正确?这是我的脚本:

@Grapes([
    @Grab(group='com.h2database', module='h2', version='1.3.160'),
    @GrabConfig(systemClassLoader = true)
])
import com.h2database.*
import groovy.sql.*
import java.sql.*

def originalMethod = Sql.metaClass.&createConnection

Connection.metaClass.createConnection = { 
  println "Called $name"
  originalMethod.invoke(this)
}

def db = Sql.newInstance('jdbc:h2:mem:', 'sa', '', 'org.h2.Driver')

// Setup database.
db.execute '''
    create table if not exists languages(
        id int primary key,
        name varchar(20) not null
    )
'''

【问题讨论】:

  • 实际的实现是什么?以及MethodClosureoriginalMethod 是如何使用的?
  • originalMethod 用于返回Connection 应用groovy.sql.Sql 的原始逻辑。 “实际实现”是指 Sql 类 impl,还是我的 createConnection 替换?
  • 你的替代品。基本上,如果可行,整个脚本作为一个可行的示例来解决问题。
  • 请注意,方法指针是在类或实例上创建的,而不是在元类上。所以使用def originalMethod = Sql.&createConnection 开始。按照您现在的方式,根据我建议的更改,由于递归调用 createConnection,您将获得 StackOverflow,因此我希望添加完整的用例将有助于找出实际问题。
  • @dmahapatro 好的,使用示例进行了编辑。

标签: groovy


【解决方案1】:

这里的问题与受保护的方法无关。问题是您正在使用 Groovy 的运行时元编程来替换现有方法,然后在从 Java 调用相关方法时期望元编程发挥作用。这种元编程风格不适用于直接从 Java 进行的方法调用。 groovy.sql.Sql 类是用 Java 编写的,因此当 groovy.sql.Sql 内部的代码调用 createConnection 方法时,会使用真正的方法,而不是元编程的方法。

【讨论】:

    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 2016-02-19
    • 2011-10-26
    • 2014-06-24
    • 2020-05-02
    相关资源
    最近更新 更多