groovy - 为什么 Groovy 闭包不能访问注入(inject)的类成员?

标签 groovy closures guice

我们在项目中使用 Groovy 和 Guice,我遇到了以下错误:

groovy.lang.MissingPropertyException: No such property: myService for class: com.me.api.services.SomeService$$EnhancerByGuice$$536bdaec

花了一点时间才弄清楚,但这是因为我引用了一个私有(private)类成员,它被注入(inject)到一个闭包中。任何人都可以阐明为什么会发生这种情况吗?

此外,还有更好的方法吗?

这是类的一个片段:

import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class MyService extends BaseService<Thing> {

    @Inject
    private ThingDao thingDao

    @Inject
    private OtherService<Thing> otherService

    @Override
    List<Thing> findAll() {
        List<Thing> things = this.dao.findAll()

        things.each { 
            //Note: This doesn't work!
            otherService.doSomething()
        }

        things
    }

我要么必须使用标准的 for 循环,要么不使用注入(inject)的成员,这往往会导致代码重复。

最佳答案

TLDR;

要么声明otherService public (删除 private 修饰符)或添加一个 getter OtherService<Thing> getOtherService(){otherService}

如果您绝对想避免通过属性公开该字段,您可以使用以下技巧:在引用您的服务的 Closure 范围之外创建一个局部变量:

OtherService<Thing> otherService=this.otherService
things.each { 
        //Note: This will work! Because now there is a local variable in the scope. 
        //This is handled by normal anonymous inner class mechanisms in the JVM.
        otherService.doSomething()
}

说明

在幕后,您的闭包是匿名类的对象,而不是具有您的私有(private)字段的对象,otherService .

这意味着它无法解析对该字段的直接引用。访问闭包内的符号将首先查看局部变量,如果未找到匹配项,则 getProperty() Closure 中的方法将被调用以查找属性,具体取决于您定义的解析策略。默认情况下,这是 OWNER_FIRST .

如果您查看 Closure#getProperty 的代码:

        switch(resolveStrategy) {
            case DELEGATE_FIRST:
                return getPropertyDelegateFirst(property);
            case DELEGATE_ONLY:
                return InvokerHelper.getProperty(this.delegate, property);
            case OWNER_ONLY:
                return InvokerHelper.getProperty(this.owner, property);
            case TO_SELF:
                return super.getProperty(property);
            default:
                return getPropertyOwnerFirst(property);
        }

您看到所有者、委托(delegate)和声明对象需要具有匹配的属性

在 groovy 中,如果你声明一个字段 private ,您不会获得自动生成的访问器方法,因此不会为外部对象公开公开任何属性。

关于groovy - 为什么 Groovy 闭包不能访问注入(inject)的类成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40915407/

相关文章:

java - ehcache session 范围在 grails 中

java - 优化两个列表比较

rust - 我如何克隆一个闭包,以便它们的类型相同?

java - guice 辅助注入(inject)工厂中通用返回类型的问题

jenkins - 将 Jenkins 管道阶段显示为失败,但不会导致整个作业失败

groovy - 无法插入敏感的环境变量

Python 类关闭 : Is It What It Called?

ios - 用户位置更新后触发的函数

java - 从 Java 构造函数调用实例方法是好是坏?

Java Servlet POST 操作未从请求中接收参数