Faker for Grails 给出变量未定义错误

Faker for Grails gives variable not defined error

我有一个配置了 spring-security-core 的 Grails 2.4.4 应用程序。我想使用 faker plugin 在 BootStrap 中生成虚假用户。但是,当我在 BootStrap 中实例化 bean fakerService 并尝试使用它时。 fakerService.firstname(),我得到一个错误:

ERROR context.GrailsContextLoaderListener  - Error initializing the application: Cannot invoke method firstName() on null object
Message: Cannot invoke method firstName() on null object

我只是 Grails 的初学者。我做错了依赖注入吗?

http://pasteboard.co/rvbihRU.png

是的,你是:)

一点背景。当您在 Groovy class 中添加 class-scope 变量(字段)时没有显式范围修饰符(例如 public、private、protected),它默认为 public 就像 classes 和方法一样。但是它在 JavaBean 意义上被认为是一个 属性,所以 Groovy 编译器创建了一个 getter 和一个 setter 为您根据名称。因此,如果您声明 def fooString bar(是否指定​​类型无关紧要),您将得到 Object getFoo()void setFoo(Object)String getBar()void setBar(String) 方法(您应该使用反编译器反编译 POGO class 并亲自查看 - 这是非常酷的东西 - 我推荐 JD-GUI,但使用您喜欢的任何东西)。如果你已经声明了其中的任何一个,Groovy 将跳过那个而不是覆盖你的。这很酷,因为您可以像对待简单的 public 字段一样对待变量,但可以随时添加 getter and/or setter 逻辑而不影响调用客户端(Groovy 或 Java,因为 Java classes 会一直调用 getter 和 setter,而 Groovy 调用 getter 和 setter 当你读或写一个 属性).

那我为什么要喋喋不休呢?依赖注入由 Spring 完成——你正在注入 Spring bean。有多种方法可以做到这一点,但 Grails 中的默认设置是使用 autoinject-by-name。因此,对于在 ApplicationContext 和特殊 class 中注册的任何 bean,如 BootStrap、集成测试等,Spring 扫描寻找 setter 的方法。它去掉 "set" 并将下一个字母小写,这就是 setter 的 "property" 名称。如果 ApplicationContext 中有一个具有该名称的 bean,Spring 将调用它 setter,传递具有该名称的 bean,如果类型同步,您的 class将引用该 bean。

您添加了一个局部变量。局部变量没有什么特别的变化,Spring 看不到它们,它们不是依赖注入的候选对象。将声明移动到 class 作用域,在 init 闭包之前,例如

class BootStrap {

   def fakerService

   def init = {
      ...
   }
}

和 Groovy 编译器将添加一个不太感兴趣的 getFakerService 方法,但也会添加一个 Spring 会看到的 setFakerService 方法。它将确定其 属性 名称为 "fakerService",查看是否存在具有该名称的 bean,然后调用 setter。这一切都发生在 Grails 调用 init 闭包之前,因此此时该值将是一个非空 FakerService 急切地等待您的调用。