Внедрение конструктора Dagger 2.0 и синглтон

можно ли одновременно использовать инъекцию конструктора Dagger 2.0 и синглтон. В документации ответа не нашел.

Пример:

@Singleton
public class MyClass {
   private final OtherClass member;

   @Inject
   public MyClass(OtherClass member){
        this.member = member;
   }
 }

Внедрение конструктора точно работает. Но гарантируется ли, что MyClass будет создан как синглтон, если я напишу @Singleton в классе?

Спасибо


person Soccertrash    schedule 20.05.2015    source источник


Ответы (1)


Да.

Поскольку Dagger 2 генерирует для вас исходный код, легко проверить, что происходит. Например, при использовании следующего модуля в сочетании с вашим MyClass:

@Component
@Singleton
public interface MyComponent {
  MyClass myClass();
}

Генерируется следующая реализация:

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerMyComponent implements MyComponent {
  private Provider<MyClass> myClassProvider;

  private DaggerMyComponent(Builder builder) {  
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {  
    return new Builder();
  }

  public static MyComponent create() {  
    return builder().build();
  }

  private void initialize(final Builder builder) {  
    this.myClassProvider = ScopedProvider.create(MyClass_Factory.create(OtherClass_Factory.create()));
  }

  @Override
  public MyClass myClass() {  
    return myClassProvider.get();
  }

  public static final class Builder {
    private Builder() {  
    }

    public MyComponent build() {  
      return new DaggerMyComponent(this);
    }
  }
}

В initialize(Builder) вы можете видеть, что ScopedProvider используется как Provider для MyClass. При вызове метода myClass() вызывается метод get() ScopedProvider, который реализован как синглтон:

public T get() {
  // double-check idiom from EJ2: Item 71
  Object result = instance;
  if (result == UNINITIALIZED) {
    synchronized (this) {
      result = instance;
      if (result == UNINITIALIZED) {
        instance = result = factory.get();
      }
    }
  }
  return (T) result;
}
person nhaarman    schedule 20.05.2015
comment
Да, ты прав. Я только просмотрел сгенерированный код моего подкомпонента. Но в основном компоненте я могу найти ScopedProvider - person Soccertrash; 21.05.2015