guice/Manual/Extensions/ThrowingProviders

ThrowingProvider

Guiceは(プロバイダによる)インスタンス生成中の例外をうまくハンドリングできない。

ThrowingProvidersはプロバイダの代替であり、チェック例外を投げることができる。

ThrowingProviderインターフェースはProviderと同様であるが、一般例外タイプを持つ。

public interface ThrowingProvider<T,E extends Exception> {
  T get() throws E;
}

それぞれのアプリケーション例外について、ThrowingProviderを拡張するインターフェースを作成するとよい。 我々のニュースウィジェットアプリケーションではFeedUnavailableExceptionを投げるFeedProviderを作成した。

public interface FeedProvider<T> extends ThrowingProvider<T, FeedUnavailableException> { }

WordlNewsFeedProviderSportsFeedProviderの実装を作成し、それらをモジュール内にてThrowingProviderBinderを使ってバインドする。

public static class FeedModule extends AbstractModule {
  protected void configure() {
    ThrowingProviderBinder.create(binder())
        .bind(FeedProvider.class, BbcFeed.class)
        .annotatedWith(WorldNews.class)
        .to(WorldNewsFeedProvider.class)
        .in(HourlyScoped.class);

    ThrowingProviderBinder.create(binder())
        .bind(FeedProvider.class, BbcFeed.class)
        .annotatedWith(Sports.class)
        .to(SportsFeedProvider.class)
        .in(QuarterHourlyScoped.class);
  }
}

最後にFeedProviderをアプリケーション全体に渡って注入する。 そのget()呼び出しではいつでもFeedUnavailableExceptionをハンドリングすべきことをコンパイラが教えてくれる。

public class BbcNewsWidget {
  private final FeedProvider<BbcFeed> worldNewsFeedProvider;
  private final FeedProvider<BbcFeed> sportsFeedProvider;

  @Inject
  public BbcNewsWidget(
      @WorldNews FeedProvider<BbcFeed> worldNewsFeedProvider,
      @Sports FeedProvider<BbcFeed> sportsFeedProvider) {
    this.worldNewsFeedProvider = worldNewsFeedProvider;
    this.sportsFeedProvider = sportsFeedProvider;
  }

  public GxpClosure render() {
    try {
      BbcFeed bbcWorldNews = worldNewsFeedProvider.get();
      BbcFeed bbcSports = sportsFeedProvider.get();
      return NewsWidgetBody.getGxpClosure(bbcWorldNews, bbcSports);
    } catch (FeedUnavailableException e) {
      return UnavailableWidgetBody.getGxpClosure();
    }
  }
}

スコーピングに関するノート

スコープもプロバイダに関して同じように動作する。 get()が呼び出されるときには、返されたオブジェクトは適切にスコープされる。 例外も同じくスコープされる。 例えば、worldNewsFeedProvider.get()が例外を投げると、その同じ例外がスコープ内のすべての呼び出し側に返される。

last edited 2009-12-16 08:46:58 by ysugimura