我希望通过替换ExpandoMetaClass的invokeMethod闭包来拦截所有控制器中的所有方法。
我创建了一个新的grails项目(2.3.5)。创建了一个名为AccountController的新Controller:
package com.invoke.test
class AccountController {
def index() {
System.out.println("Index Called")
}
}
然后创建了另一个名为SecurityBootStrap的BootStrap:
class SecurityBootStrap {
def grailsApplication
def verifyMethodAccess = { String name, args ->
log.info "Called method ${name}"
def method = delegate.metaClass.getMetaMethod(name, args)
if (method) {
return method.invoke(delegate, args)
}
return null
}
def init = { servletContext ->
grailsApplication.controllerClasses.each { controllerClass ->
controllerClass.clazz.metaClass.invokeMethod = verifyMethodAccess
log.info "Replaced the invokeMethod closure on ${controllerClass.clazz}"
}
}
}
启动应用程序后,日志看起来很有希望:
|Running Grails application
2014-06-26 15:07:26,476 [localhost-startStop-1] INFO conf.SecurityBootStrap - Replaced the invokeMethod closure on class grails.plugin.databasemigration.DbdocController
2014-06-26 15:07:26,477 [localhost-startStop-1] INFO conf.SecurityBootStrap - Replaced the invokeMethod closure on class com.invoke.test.AccountController
|Server running. Browse to http://localhost:8080/InvokeTest
但是,当调用http://localhost:8080/InvokeTest/account/index
时,日志看起来像:
Index Called
我原以为:
Called method index
Index Called
提前致谢
答案 0 :(得分:1)
您可以使用编译时元编程来执行此操作,但不能通过运行时元编程来执行此操作。 Groovy运行时元编程的一个限制是它只适用于从Groovy启动的方法调用。许多Grails框架都是用Java编写的。
示例:
class Widget {
def getTheAnswer() {
42
}
}
Widget.metaClass.getTheAnswer = { ->
2112
}
当Groovy代码调用new Widget().getTheAnswer()
时,结果将是2112.当Java代码调用new Widget().getTheAnswer();
时,结果将为42。