Grails 为什么使用与配置的SpringBean名称相同的操作名称会导致ClassCastException?
要重现此问题,请使用以下步骤Grails 为什么使用与配置的SpringBean名称相同的操作名称会导致ClassCastException?,grails,classcastexception,autowired,grails-controller,Grails,Classcastexception,Autowired,Grails Controller,要重现此问题,请使用以下步骤 创建一个新的Grails应用程序 创建一个名为FooController的新控制器 向FooController添加操作“栏” 在src/groovy中,创建一个名为Bar的新类 在resources.groovy中配置名为bar的SpringBean bar(bar){bean-> bean.autowire='byName' } 启动应用程序并导航到http:localhost:8080/[appContext]/foo/bar 您应该获得类似以下内容的stac
bar(bar){bean->
bean.autowire='byName'
}
java.lang.ClassCastException:Bar不能强制转换为groovy.lang.Close
位于org.grails.plugin.resource.DevModeSanityFilter.doFilter(DevModeSanityFilter.groovy:44)
运行(Thread.java:680)
为什么会这样?这是Grails中的bug还是预期的行为
我希望配置的SpringBeans和操作名称之间不会有名称冲突。控制器中的操作是一个闭包,它被转换为一个内部类。你的bean有相同的名字,所以我相信你是通过这个来命名冲突的。您是否尝试重命名bean或操作?问题在于Groovy语法
class FooController {
def bar = {
// do something
}
}
给出FooController
类2的公共方法
public Object getBar() {
return bar;
}
public void setBar(Object newBar) {
bar = newBar;
}
< <代码> > SETBAR < /C>方法的存在使得Spring将其视为一个自动存储的属性,并用bean替换该闭包值。Grails本身只需要getter方法,所以如果
class FooController {
final bar = {
// do something
}
}
(即,将
bar
声明为final
)然后Groovy将只合成getter而不是setter,Spring将不会将bar
视为它可以自动连接的属性。重命名操作或bean显然可以解决问题,但这不是这里的问题……Grails的哪个版本,如果2.x是你的bar
操作,一个闭包还是一个方法?Grails 1.3.7,我也会尝试在2.x上重现这个问题。我在Grails 2.0.3上尝试过这个方法,它可以使用方法和闭包作为操作。也许解决方案显而易见:升级我在项目中使用的Grails版本。:-)我仍然想知道为什么会在1.3.7上出现这种情况。。。感谢您的评论。在Grails2上,actions as methods是首选方法,任何声明为闭包的操作都会在编译时通过AST转换转换转换为方法。Spring仍在用AutowiredBean替换控制器的bar
属性的值,但当通过web请求调用操作时,运行的是方法版本(它有自己的原始闭包代码副本)。太棒了!我测试了解决方案,现在操作正常。我以前曾多次遇到过这个问题,只是更改了操作名称,但始终没有找到问题的根源。谢谢你的帮助。