首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Groovy Mixins?

Groovy Mixins?
EN

Stack Overflow用户
提问于 2009-01-08 19:50:19
回答 7查看 10K关注 0票数 10

我尝试在我的Groovy/Grails应用程序中混入一个类,我使用的是the syntax defined in the docs,但我总是得到一个错误。

我有一个如下所示的域类:

代码语言:javascript
复制
class Person {
  mixin(ImagesMixin)

  // ...
}

它编译得很好,但由于某些原因,它不能工作。包含ImagesMixin的文件位于我的/src/groovy/目录中。

我在Groovy 1.5.7和1.6-RC1版本中尝试过,但没有成功。有人知道我做错了什么吗?

堆栈跟踪:

代码语言:javascript
复制
2008-12-30 17:58:25.258::WARN:  Failed startup of context org.mortbay.jetty.webapp.WebAppContext@562791{/FinalTransmission,/home/kuccello/Development/workspaces/lifeforce/FinalTransmission/web-app}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError
    at java.security.AccessController.doPrivileged(Native Method)
    at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy:67)
    at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy)
    at Init_groovy$_run_closure6.doCall(Init_groovy:131)
    at RunApp_groovy$_run_closure2.doCall(RunApp_groovy:66)
    at RunApp_groovy$_run_closure2.doCall(RunApp_groovy)
    at RunApp_groovy$_run_closure1.doCall(RunApp_groovy:57)
    at RunApp_groovy$_run_closure1.doCall(RunApp_groovy)
    at gant.Gant.dispatch(Gant.groovy:271)
    at gant.Gant.this$2$dispatch(Gant.groovy)
    at gant.Gant.invokeMethod(Gant.groovy)
    at gant.Gant.processTargets(Gant.groovy:436)
    at gant.Gant.processArgs(Gant.groovy:372)
Caused by: java.lang.ExceptionInInitializerError
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)
    at Episode.class$(Episode.groovy)
    at Episode.<clinit>(Episode.groovy)
    ... 13 more
Caused by: groovy.lang.MissingMethodException: No signature of method: static Person.mixin() is applicable for argument types: (java.lang.Class) values: {class ImagesMixin}
    at Broadcast.<clinit>(MyClass.groovy:17)
    ... 17 more
2008-12-30 17:58:25.259::WARN:  Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError:
groovy.lang.MissingMethodException: No signature of method: Person.mixin() is applicable for argument types: (java.lang.Class) values: {class ImagesMixin}
    at Broadcast.<clinit>(Person.groovy:17)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)
    at Episode.class$(BelongsToMyClass.groovy)
    at Episode.<clinit>(BelongsToMyClass.groovy)
    at java.security.AccessController.doPrivileged(Native Method)
    at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy:67)
    at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy)
    at Init_groovy$_run_closure6.doCall(Init_groovy:131)
    at RunApp_groovy$_run_closure2.doCall(RunApp_groovy:66)
    at RunApp_groovy$_run_closure2.doCall(RunApp_groovy)
    at RunApp_groovy$_run_closure1.doCall(RunApp_groovy:57)
    at RunApp_groovy$_run_closure1.doCall(RunApp_groovy)
    at gant.Gant.dispatch(Gant.groovy:271)
    at gant.Gant.this$2$dispatch(Gant.groovy)
    at gant.Gant.invokeMethod(Gant.groovy)
    at gant.Gant.processTargets(Gant.groovy:436)
    at gant.Gant.processArgs(Gant.groovy:372)
2008-12-30 17:58:25.271::INFO:  Started SelectChannelConnector@0.0.0.0:8080
EN

回答 7

Stack Overflow用户

发布于 2009-08-13 20:42:52

从Groovy1.6开始,您可以在编译时使用注解将混合应用于类

代码语言:javascript
复制
@Mixin(ImagesMixin)
class Person {
}

或者,您可以在运行时应用混合,如下所示:

代码语言:javascript
复制
def myMixin = ImagesMixin
Person.mixin myMixin

后一种方法更具动态性,因为可以在运行时确定要混合的类。有关Groovy的更多信息,请访问here

根据我的经验,许多域类的元编程根本不起作用。我不知道确切的原因,但我怀疑这是因为这些类已经由Grails运行时进行了大量元编程。一般来说,我的方法是

  • 在Groovy控制台
  • 中的POGO上尝试元编程如果可行,在

控制台

  • 中的非域类上试用如果可行,在Grails控制台中的域类上试用。如果它不能工作,那一定是因为它是一个域类(而不是语法问题)。在这一点上,明智的做法是尝试寻找另一种方法来实现您的目标。如果这是不可能的,那么使用Grails邮件列表和/或Stackoverflow和/或Grails源代码的组合来尝试让元编程工作。
票数 12
EN

Stack Overflow用户

发布于 2009-01-22 15:07:20

我不认为你使用了正确的混入语法。试试这个:

代码语言:javascript
复制
class MyMixin {
    static doStuff(Person) {
        'stuff was done'
    }
}

class Person {}

Person.mixin MyMixin

new Person().doStuff()
票数 11
EN

Stack Overflow用户

发布于 2009-01-08 20:16:37

我猜您看到的是一个提议而不是一个特性;) Groovy还不支持以这种方式开箱即用的混入(如果有的话)。但是有一个第三方库可以用来模仿这样的行为:Injecto。并且可以在Groovy的1.6版本(尚未完成)中使用AST-Macros定义混入。

你应该总是检查你是从真实的groovy项目还是从GroovyJSR项目(这是一个收集建议书的地方)阅读文档。

另一种方法是使用普通的MOP通过修改metaClasses将行为注入groovy类。

干杯

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/425617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档