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