将Groovy动态方法添加到Spring控制器

时间:2014-05-07 10:07:26

标签: java spring spring-mvc groovy

有一个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

1 个答案:

答案 0 :(得分:0)

你有这个......

MyCtrl ctrl = applicationContext.getBean(...)
ctrl.metaClass.render = { String x ->
    ...
}

这不是修改MyCtrl元类。那就是修改MyCtrl特定实例的元类。延迟您的应用中的一些其他因素,这些因素在您的描述中不存在,可能不是您想要的。您可能希望使用类似的内容修改MyCtrl元类...

MyCtrl.metaClass.render = { String x ->
    ...
}