有一个Groovy Spring应用程序,我试图在app start上向控制器类添加一个方法。像:
@Configuration
class AppConfig implements InitializingBean {
void afterPropertiesSet() throws Exception {
MyCtrl ctrl = applicationContext.getBean(...)
ctrl.metaClass.render = { String x ->
...
}
}
}
对于Groovy类,如:
@Controller
class MyCtrl {
ModelAndView show() {
...
println this.metaClass.methods*.name
println MyCtrl.metaClass.methods*.name
println this
println this.class == MyCtrl
render('show')
}
}
获得例外:
groovy.lang.MissingMethodException: No signature of method: com.company.MyCtrl.render() is applicable for argument types: (java.lang.String) values: [/index]
Possible solutions: render(java.lang.String), index(), find(), every(), every(groovy.lang.Closure), find(groovy.lang.Closure)
请注意,Groovy在"可能的解决方案"中提到了这种方法。列表。
在控制台中,我看到以下内容:
[equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait, __$swapInit, getMetaClass, getProperty, index, invokeMethod, setMetaClass, setProperty]
[render, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait, __$swapInit, getMetaClass, getProperty, index, invokeMethod, setMetaClass, setProperty]
com.company.MyCtrl@3e52f8c1
true
如我所见,this.metaClass
没有看到我的动态方法render
,但MyCtrl.metaClass
看到了它。当然,它是同一类MyCtrl == this.getClass()
区别是什么?我在那里错过了什么?试图使用ExpandoMetaClass
和/或应用类而不是实例,结果相同。不行。
这不是我第一次通过metaClass添加方法,并且始终正常工作。刚刚第一次添加到Spring Controller。也许它与用于控制器的Spring反射相冲突?不知道如何检查
PS Groovy 2.3,Java 7,Spring 4.0.3
答案 0 :(得分:0)
你有这个......
MyCtrl ctrl = applicationContext.getBean(...)
ctrl.metaClass.render = { String x ->
...
}
这不是修改MyCtrl
元类。那就是修改MyCtrl
特定实例的元类。延迟您的应用中的一些其他因素,这些因素在您的描述中不存在,可能不是您想要的。您可能希望使用类似的内容修改MyCtrl
元类...
MyCtrl.metaClass.render = { String x ->
...
}