2016-12-01 47 views
1

我們是在一個項目中使用Groovy和Guice和我碰到下面的錯誤來了:爲什麼Groovy閉包不能訪問注入的類成員?

groovy.lang.MissingPropertyException: No such property: 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 
    } 

我要麼必須使用標準的循環或不使用注射的成員,然後往往會導致代碼重複。

+2

與Guice沒有任何關係。該字段是「private」,因此Groovy不會爲其生成訪問者。 –

+1

在普通的Groovy中,私有類字段可以從閉包訪問。但是,請記住私人字段正在注入* class *實例,而不是關閉。關閉的解決/委派策略開始發揮作用,需要在閉包中查找。試着張貼一個更徹底地展示你的問題的例子。 –

回答

1

TLDR;

要麼宣佈otherService公共(刪除private改性劑)或添加getter OtherService<Thing> getOtherService(){otherService}

如果絕對 wnat避免通過屬性暴露的領域,你可以做下面的技巧:創建外的一個局部變量引用您的服務結束範圍:

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() 
} 

說明

引擎蓋下,你是封一個匿名對象,而不是具有您的專用字段的實例otherService

這意味着它無法解析對該字段的直接引用。在閉包中訪問符號將首先查看局部變量,如果找不到匹配,則將調用Closure中的getProperty()方法來查找屬性,具體取決於您定義的分辨率策略。默認情況下,這是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); 
     } 

你看主人,委託和申報的對象需要有匹配性質

在groovy中,如果你聲明瞭一個字段private,你將不會獲得自動生成的存取方法,所以沒有屬性將公開地暴露給外部對象。

+0

非常感謝你的回答。這真的有助於澄清事情。事後看來,這應該是顯而易見的。 ;) –

相關問題