圣杯。使用@GrailsCompileStatic 时如何处理 'mixed' 方法和变量

Grails. How to handle the 'mixed' methods and variables when using @GrailsCompileStatic

我很想在我的 grails 3.1.7 应用程序的许多地方使用 @GrailsCompileStatic 注释。但主要问题是它没有考虑到域、命令和控制器是 'mixed' 和其他方法(如 save()validate())或变量(如 g).

我找到了上述方法的解决方法:我从具有空 save() 方法的抽象 class 继承域和命令(它的实现随后被 grails 覆盖,但静态编译不会'不会失败)。此外,此抽象 class 通过 validate() 方法实现实现了 grails.validation.Validateable 特征。

但是有没有更好的方法来启用静态编译而无需这些肮脏的技巧?

在许多控制器中,我使用 g.createLink() 方法。我应该如何在内部传递 g 变量以避免在静态编译期间出现这种情况?

Error:(37, 39) Groovyc: [Static type checking] - The variable [g] is undeclared.

据我所知,@GrailsCompileStatic 已经允许您使用像 save() 这样的方法。 就我而言,这只是 groovy eclipse 插件的问题,而 grails 运行-app 工作正常。

无论如何,自 grails 3 起,"implementing" trait 可以直接访问 traits 提供的方法,如文档所述 here

The traits are compatible with static compilation…​

class TestController implements Controller {
        @GrailsCompileStatic
        def index() {
            render "test"
        }
    }

g 好像是NamespacedTagDispatcher 类型,它在运行时使用methodMissing 找到被调用的方法。即使您可以在编译时访问 g,g.createLink() 也不会编译。

您可以将性能关键代码提取到另一个方法中并使用 @CompileStatic 对其进行注释,或者编写一个调用 g.createLink()

的未注释方法

补充@andi 的回答,只是为了添加 g.createLink() 问题的解决方案:
您可以注入一个 LinkGenerator bean 并根据需要使用静态编译。

注意:您必须像这样注入依赖项:

LinkGenerator grailsLinkGenerator

并从包 grails.web.mapping

中导入 class