Constructor Injection

さて、今回はInjectの仕方についてです。

前回までは特に何も考えずPrivate Fieldに対して@InjectアノテーションでInjectを指示してきました。

この場合Default Constructorでオブジェクトが作成された後にPrivate Fieldに対してInjectionが行われます。

というわけでConstructorによるInjection。

例えばprivate finalなfieldを使いたい場合はConstructorで設定しないと問題になります。こういう場合はConstructorに対して@Injectアノテーションを付けてConstructorの呼び出し時に注入を行います。

import com.google.inject.Inject;

public class Client {
  
    private **final** Service service;
  
    private static int objCount = 0;
  
    private final int number;

    **@Inject**
  
    public Client(Service _service) {
  
        this.service = _service;
  
        objCount++;
  
        number = objCount;
  
        System.out.println(“Create instance ” + number);
  
    }

    public void execute() {
  
        System.out.println(service.getResponse(“Guice” + number));
  
    }

    public Service getService() {
  
        return service;
  
    }

    public int getNumber() {
  
        return number;
  
    }
  
}

この場合Injector側でオブジェクトを作成するときにDefault Constructorではなく、パラメータ付のConstructorが呼び出されてInjectionされる事になります。

続いてMethodによるInjection。

PropertyのSetterが副作用を持つ場合等はFieldに直接注入するのではなくSetterの呼び出しでInjectionしたくなります。もう予想ついてると思いますが、こういう場合は以下。

import com.google.inject.Inject;

public class Client {
  
    private final Service service;
    private static int objCount = 0;
    private final int number;

    public Client() {
        objCount++;
        number = objCount;
        System.out.println("Create instance " + number);
    }

    public void execute() {
        System.out.println(service.getResponse("Guice" + number));
    }

    public Service getService() {
        return service;
    }

    @Inject
    private void setService(Service _service) {
        this.service = _service;
        System.out.println("Service Injected.");
    }

    public int getNumber() {
        return number;
    }
  
}

これらのField/Constructor/Method Injectionは併用できますので必要に応じてInjectionの仕方を変更する事が可能です。

余談

Constructorは問答無用で一番最初にInjectionされる事になりますが、FieldとMethodのどちらが先か?

簡単な実験ではConstructor→Field→Methodの順番でした。ただ、順番に依存するような実装は避けるべきでしょう。