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

要重现此问题,请使用以下步骤

  • 创建一个新的Grails应用程序
  • 创建一个名为FooController的新控制器
  • 向FooController添加操作“栏”
  • 在src/groovy中,创建一个名为Bar的新类
  • 在resources.groovy中配置名为bar的SpringBean

    bar(bar){bean->
    bean.autowire='byName'
    }

  • 启动应用程序并导航到http:localhost:8080/[appContext]/foo/bar
  • 您应该获得类似以下内容的stacktrace:
  • 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请求调用操作时,运行的是方法版本(它有自己的原始闭包代码副本)。太棒了!我测试了解决方案,现在操作正常。我以前曾多次遇到过这个问题,只是更改了操作名称,但始终没有找到问题的根源。谢谢你的帮助。