为什么';Groovy闭包是否可以访问注入的类成员?

为什么';Groovy闭包是否可以访问注入的类成员?,groovy,closures,guice,Groovy,Closures,Guice,我们在一个项目中使用Groovy和Guice,我遇到了以下错误: groovy.lang.MissingPropertyException:没有这样的属性:myService for class:com.me.api.services.SomeService$$EnhancerByGuice$$536bdaec 花了一点时间才弄明白,但这是因为我引用了一个私有类成员,它被注入到闭包中。有人能解释为什么会发生这种情况吗 此外,有没有更好的办法 下面是该类的一个片段: import javax.in

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

groovy.lang.MissingPropertyException:没有这样的属性:myService for class:com.me.api.services.SomeService$$EnhancerByGuice$$536bdaec

花了一点时间才弄明白,但这是因为我引用了一个私有类成员,它被注入到闭包中。有人能解释为什么会发生这种情况吗

此外,有没有更好的办法

下面是该类的一个片段:

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
    }
import javax.inject.inject
导入javax.inject.Singleton
@独生子女
类MyService扩展了BaseService{
@注入
私人的东西
@注入
私人其他服务其他服务
@凌驾
列表findAll(){
List things=this.dao.findAll()
每件事{
//注意:这不起作用!
otherService.doSomething()
}
东西
}
我要么使用循环的标准,要么不使用注入的成员,这会导致代码重复。

TLDR; 声明
otherService
public(删除
private
modifier)或添加getter
otherService getOtherService(){otherService}

如果绝对不想通过属性公开字段,可以执行以下技巧:在引用服务的闭包范围之外创建一个局部变量:

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()
}
您可以看到,所有者、委托和声明对象需要具有匹配的属性


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

与Guice没有任何关系。该字段是
private
,因此groovy不会为其生成访问器。在普通groovy中,可以从clos访问私有类字段但是,请记住,私有字段被注入到类实例中,而不是闭包中。闭包的解决/委派策略开始发挥作用。需要在闭包中查找某些内容。请尝试发布一个更全面地说明问题的示例。
        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);
        }