覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Guice - Listに名前を付けて@NamedでInjectionしたい

Guiceを使っている場合に@NamedでListに名前を付けて依存関係を解決するサンプルです。

今回のサンプルではList<String>の値に sample.list という名前を付けてInjection出来るようにします。


依存関係を記述

■ListがInjectionされるクラス

コンストラクタで@Namedsample.list という値を指定して List<String> の値を受け取るようにしてます

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;

@Singleton
public class SampleList {

    private final List<String> list = new ArrayList<>();

    @Inject
    public SampleList(@Named("sample.list") List<String> srcList) {
        this.list.addAll(srcList);
    }

    public List<String> list() {
        return list;
    }
}


■GuiceのModuleのクラスを定義

GuiceのModuleのクラスを定義して、sample.list という名前で、文字列Listをbindします
TypeLiteralを利用するのがポイントです

import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;

import java.util.Arrays;
import java.util.List;

public class SampleModule extends AbstractModule {

    @Override
    protected void configure() {
        // 紐づけしたいデータ
        List<String> targetList = Arrays.asList("data1", "data2", "data3");

        bind(new TypeLiteral<List<String>>() {})
                .annotatedWith(Names.named("sample.list")).toInstance(targetList);

        // これではダメ
        // bind(List.class)
        //         .annotatedWith(Names.named("sample.list")).toInstance(targetList);
    }
}


実行

■実行用のサンプルクラス

上で定義したModuleを使ってGuiceのInjectorを生成します。これで準備完了です。

import com.google.inject.Guice;
import com.google.inject.Injector;

public class Launcher {

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new SampleModule());

        SampleList sampleList = injector.getInstance(SampleList.class);

        System.out.println("SampleList#list -> " + sampleList.list());
    }
}


■実行結果

SampleList#list -> [data1, data2, data3]

sample.list という名前を付けた文字列ListがうまくInjectionされていることが分かります