Google Guice を DI フレームワークとしてチェックアウトしていますが、少し戸惑っています: 構成ファイルがまったくないのはなぜですか?
この質問に関する部分的な説明を見つけましたが、構成ファイルなしでコンポーネントの役割 (またはスイッチを使用する必要があるその他のもの) を設定する方法はまだ明確ではありません。
どんな助けでも大歓迎です!
Google Guice を DI フレームワークとしてチェックアウトしていますが、少し戸惑っています: 構成ファイルがまったくないのはなぜですか?
この質問に関する部分的な説明を見つけましたが、構成ファイルなしでコンポーネントの役割 (またはスイッチを使用する必要があるその他のもの) を設定する方法はまだ明確ではありません。
どんな助けでも大歓迎です!
構成は構成ファイルではなくコード内にあり、これは多くのシナリオで有効な決定です。
はい、アプリケーションを配管する別の方法をリリースしたい場合は、(おそらくモジュールだけを) 再構築する必要があることを意味します - もちろん、必要に応じて、コマンドライン引数、プロパティ ファイルなどからいくつかの構成値を取得することもできますが、に。
アプリケーションの配管を定期的に変更する必要があり、単一のファイル以外は再デプロイしたくない場合は、Guice は適していない可能性があります。一方、DI を使用する主な理由がコードをより明確にすることであり、本番環境では常に同じ配管を使用する (または十分に近い) 場合は、Guice が適切なオプションです。多くの場合、必要なロジックがいくつかあります。とにかく配管を整理するときに使用し、宣言的に記述/構築するのが一般的に難しいコンポーネント。
DI フレームワークが異なれば、利点とトレードオフも異なります。アプリケーションに最も適したものを使用してください。
気になる場合は、構成ファイルを使用してブーストラッピングを導入するのは簡単です。GuiceをシンプルなAPIと一緒に使用して、実際にパラメーター化する必要のあるものが移動するプロパティファイルをロードします。これは@Namedアノテーションなどと一緒に使用できます。もちろん、モジュールにいくつかの条件を含めることができます(ただし、やりすぎないことをお勧めします)。
これは、ブートストラップの一部がどのように設定されているかの例です。
public class MetModules extends AbstractModule {
private static final Logger log = LoggerFactory.getLogger(MetModules.class);
private final Settings settings;
public MetModules(Settings settings) {
this.settings = settings;
}
@Override
protected void configure() {
// common (stage independent modules) go here
install(new CommandsModule());
install(new ServletsModule());
install(new DataBaseModule(settings));
install(new JobsModule(settings));
// any development/ production specific modules
Stage stage = currentStage();
if (Stage.DEVELOPMENT.equals(stage)) {
configureForDevelopment();
} else { // PRODUCTION
configureForProduction();
}
}
/**
* Install modules that will be used in development.
*/
private void configureForDevelopment() {
// Mock implementation of email delivery that just logs it got a
// message rather than trying to send it.
install(new AbstractModule() {
@Override
protected void configure() {
bind(Delivery.class).toInstance(new Delivery() {
public String deliver(MailMessageExchange exchange)
throws DeliveryException {
log.info("email message: "
+ exchange.getMessage().getMailMessage()
+ " to "
+ Arrays.asList(exchange.getMessage()
.getMailMessage().getTo())
+ " (not sent)");
return "fooMessageId";
}
});
}
});
// local in-memory registry suffices
install(new LocalServiceRegistryModule());
// local in memory db implementations of services
install(new LocalServicesModule());
}
/**
* Install modules that will be used in production.
*/
private void configureForProduction() {
// we really only need this (error interception and audit logging)
// in production
install(new AopModule());
install(new ZooKeeperServiceRegistryModule()); }
}
ここで、設定はプロパティファイルなどを読み取るものです。現在、開発/本番環境とデプロイメントに固有の特定の設定オーバーライドが機能しているようですが、明らかに必要な場合は、これをさらに進めることができます。
ほとんどの DI 構成はデプロイメントごとに同じであるため、コードを使用して非常にうまく構成できます。これにより、Guice の構成が非常に簡潔になり、コンパイル時の型チェック、リファクタリング ツール、コード ナビゲーションなどの利点が得られます。
データベースのユーザー名とパスワードの構成など、展開ごとに変更されるいくつかの点については、必要なコードを自分で作成できます。アプリケーションがアクセスできるように、構成ファイル (おそらくプロパティ ファイル) を読み取り、パラメーターを解析し、それらを Guice モジュールにバインドするコードを記述します。それを行うために必要なコードは、多くのコード行を必要としません。
Guice の構成の多くは、@Inject アノテーションを介して暗黙的に行われます。プロジェクトが非常に複雑になるのは、多数のプロジェクト アーティファクトによるものです。Java ファイル、Xml ファイル、プロパティ ファイル、データベース、パラメーター..Guice は、構成ファイルを使用しないことで、この複雑さの一部を取り除こうとします。
コンパイル時にアプリケーションを再配線するのは簡単です。ほとんどの場合、モジュール クラスを編集するだけで済みます。Guice によって処理されるほとんどのクラスでは、構成はまったく必要ありませんが、適切な場所に @Inject のみが必要です。同じインターフェイスの 2 つの異なる実装がある場合、またはクラスを注入する場合にのみ、何かを構成する必要があります。 Provider クラスを使用する外部ライブラリ。
最近、次のプロジェクトを作成しました。
http://code.google.com/p/guice-property-injector/
これは WIP ですが、環境に基づいてプロパティ ファイルからプロパティを実行時に挿入できます。