2016-12-01 7 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では、プライベートクラスのフィールドにはクロージャからアクセスできます。しかし、プライベートフィールドは、クロージャではなく*クラス*インスタンスに注入されていることに注意してください。クロージャの解決/委任戦略は、クロージャ内で何かを探す必要があります。あなたの問題をより完全に実証した例を投稿してみてください。 –

答えて

1

TLDR;

どちらの宣言otherServiceパブリック(private修飾子を削除)またはゲッターに追加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

これは、フィールドへの直接参照を解決できないことを意味します。クロージャ内のシンボルにアクセスすると、まずローカル変数が検索され、一致するものが見つからない場合は、ClosuregetProperty()メソッドが呼び出され、定義した解決方法に応じてプロパティが検索されます。既定では、これは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

ありがとうございました。それは本当に物事を明確にするのに役立ちます。後見では、それは明らかだったはずです。 ;) –

関連する問題