2017-09-25 4 views
2

私はJersey 2.25HK2 2.5-b30)というプロジェクトを持っています。もともと、私はHK2-Guice Bridgeを使っていました。しかし、いくつかのケースでは予期せず失敗するようです(特に、Guiceで設定されたカスタム注釈で注釈が付けられ、Guiceがインジェクションを行っているときにはうまく動作しますが、HK2がインジェクションしているときには静かに失敗します)。同じオブジェクトが注入方法によって異なる動作をする可能性があるため、私は両方を同時に使用することに恐怖を感じています。明示的に設定されていないクラスを注入するためにGuiceのようなHK2を動作させるにはどうすればよいですか?

私は今、HK2を使用するためにすべてを切り替えていますが、残念ながら、Guiceが成功する特定のケースではHK2が失敗するようです。特に、HK2は、タイプが明示的に構成されていない場合の注入を好まないようです。 Guiceはこれらのクラスの新しいインスタンスを作成し、再帰的に注入するだけで満足しましたが、HK2はあまりありません。例えば、

1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=TimeRangeRequestValidator,parent=GetWatchlistEventsImpl,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1218743359)

あなたが見ることができるように、エラーメッセージは全く非常に有用ではありません。 Guiceが問題なく作成できた他のオブジェクトを参照するTimeRangeRequestValidatorを作成できるはずです。 HK2とGuiceとの間に違う行動のリストがあるので、これがなぜ機能していないのかを追跡できますか?

TimeRangeRequestValidatorは、デフォルトのパブリックコンストラクタとInjectと注釈されたフィールドを持つ@Singletonと注釈されたクラスです(インターフェイスではありません)。 Guiceはそれをインスタンス化することに問題はなかった。

答えて

2

グリーディJustInTimeResolverを使用することもできます。それはあなたが期待されていない可能性がありますあなたのServiceLocatorに物事を追加しますと上記のリゾルバを使用するときは注意する必要があり

@Singleton 
@Visibility(DescriptorVisibility.LOCAL) 
public class GreedyResolver implements JustInTimeInjectionResolver { 
    private final ServiceLocator locator; 

    @Inject 
    private GreedyResolver(ServiceLocator locator) { 
     this.locator = locator; 
    } 

    @Override 
    public boolean justInTimeResolution(Injectee failedInjectionPoint) { 
     Type type = failedInjectionPoint.getRequiredType(); 
     if (type == null) return false; 

     Class<?> clazzToAdd = null; 
     if (type instanceof Class) { 
      clazzToAdd = (Class<?>) type; 
     } 
     else if (type instanceof ParameterizedType) { 
      Type rawType = ((ParameterizedType) type).getRawType(); 
      if (rawType instanceof Class) { 
       clazzToAdd = (Class<?>) rawType; 
      } 
     } 

     if (clazzToAdd == null) return false; 
     if (clazzToAdd.isInterface()) return false; 

     ServiceLocatorUtilities.addClasses(locator, clazzToAdd); 
     return true; 
    } 

} 

:私は、以下のものを書いています。それはまた、ストリングやそのような他のタイプのようなものを注入するとうまくやらないでしょう。それでも、あなたのユースケースのために働く可能性があります。

注射ポイントがインターフェイスを注入している場合は機能しません!

+0

Yup;これは私が必要とするもののように見えます。私は実際に私が注射したいものを注入していることを確認するためにいくつかのチェックを追加します。私はこれがGuiceブリッジが使っているものとまったく同じだと考えていますが、少なくともそれを明示的に行うと、より多くの可視性と制御が得られます。 –

1

あなたのサービスを自動的に取り込むにHK2を設定するには、a few extra steps you needがあります

  1. あなたはビルド中にHK2 Metadata Generatorを実行する必要が@Service
  2. であなたが@Contractとあなたの実装とあなたのインタフェースを注釈を付けていることを確認します。これにより、実行時にHK2が必要とするサービスファイルが生成され、どのクラスがどのコントラクトインタフェースを実装するかを決定します。
  3. ServiceLocatorUtilities.createAndPopulateServiceLocator()を使用してServiceLocatorインスタンスを取得します。

使用しているフレームワーク(ジャージーなど)によって、動作の仕組みや仕組みが異なることに注意してください。 Using HK2 with Jerseyを参照してください。

関連する問題