Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

読むと怖くないDagger2

androidの勉強会 kyobashi.dex #!で発表した内容です。

読むと怖くないDagger2

  1. 1. 読むと怖くないDagger2 kyobashi.dex #1
  2. 2. プロフィール 釘宮 愼之介 / @kgmyshin Androidエンジニア 福岡県福岡市南区野多目出身
  3. 3. この資料の目的 Dagger2で生成されるソースを読んで、 動きを理解する
  4. 4. 今回話さないこと •DIとは •Dagger2の使い所 •どういう構成にするか •DaggerとDagger2の違い
  5. 5. 今回話すこと ひたすら生成されたソースを見て 裏でどういう動きをするのかを見る
  6. 6. Target Annotation •Component •Module •Singleton •Inject •Scope
  7. 7. Target Annotation •Component •Module •Singleton •Inject •Scope 時間的に無理でした
  8. 8. Case 1 Minimum
  9. 9. public interface Bread {
 } public class Chokokorone implements Bread {
 }
  10. 10. @Component(modules = BreadModule.class)
 interface BreadShop {
 Bread bread();
 } @Module
 public class BreadModule {
 @Provides
 Bread provideBread() {
 return new Chokokorone();
 }
 }
  11. 11. BreadShop shop = DaggerBreadShop
 .builder()
 .breadModule(new BreadModule())
 .build(); Bread bread = shop.bread();
  12. 12. BreadShop shop = DaggerBreadShop
 .builder()
 .breadModule(new BreadModule())
 .build(); Bread bread = shop.bread(); // Chokokorone
  13. 13. Generated Codes • DaggerBreadShop • BreadModule_ProvideBreadFactory
  14. 14. @Generated("dagger.internal.codegen.ComponentProcessor")
 public final class DaggerBreadShop implements BreadShop {
 private Provider<Bread> provideBreadProvider;
 
 private DaggerBreadShop(Builder builder) { 
 assert builder != null;
 initialize(builder);
 }
 
 public static Builder builder() { 
 return new Builder();
 }
 
 public static BreadShop create() { 
 return builder().build();
 }
 
 private void initialize(final Builder builder) { 
 this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule);
 }
 
 @Override
 public Bread bread() { 
 return provideBreadProvider.get();
 }
 
 public static final class Builder {
 private BreadModule breadModule;
 
 private Builder() { 
 }
 
 public BreadShop build() { 
 if (breadModule == null) {
 this.breadModule = new BreadModule();
 }
 return new DaggerBreadShop(this);
 }
 
 public Builder breadModule(BreadModule breadModule) { 
 if (breadModule == null) {
 throw new NullPointerException("breadModule");
 }
 this.breadModule = breadModule;
 return this;
 }
 }
 }
  15. 15. }
 
 public static final class Builder {
 private BreadModule breadModule;
 
 private Builder() { 
 }
 
 public BreadShop build() { 
 if (breadModule == null) {
 this.breadModule = new BreadModule();
 }
 return new DaggerBreadShop(this);
 }
 
 public Builder breadModule(BreadModule breadModule) { 
 if (breadModule == null) {
 throw new NullPointerException("breadModule");
 }
 this.breadModule = breadModule;
 return this;
 }
 }

  16. 16. }
 
 public static final class Builder {
 private BreadModule breadModule;
 
 private Builder() { 
 }
 
 public BreadShop build() { 
 if (breadModule == null) {
 this.breadModule = new BreadModule();
 }
 return new DaggerBreadShop(this);
 }
 
 public Builder breadModule(BreadModule breadModule) { 
 if (breadModule == null) {
 throw new NullPointerException("breadModule");
 }
 this.breadModule = breadModule;
 return this;
 }
 }

  17. 17. @Generated("dagger.internal.codegen.ComponentProcessor")
 public final class DaggerBreadShop implements BreadShop {
 private Provider<Bread> provideBreadProvider;
 
 private DaggerBreadShop(Builder builder) { 
 assert builder != null;
 initialize(builder);
 }
 
 private void initialize(final Builder builder) { 
 this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule);
 }
 
 @Override
 public Bread bread() { 
 return provideBreadProvider.get();
 }
 
 public static final class Builder {
 private BreadModule breadModule;
 
 private Builder() { 

  18. 18. @Generated("dagger.internal.codegen.ComponentProcessor")
 public final class DaggerBreadShop implements BreadShop {
 private Provider<Bread> provideBreadProvider;
 
 private DaggerBreadShop(Builder builder) { 
 assert builder != null;
 initialize(builder);
 }
 
 private void initialize(final Builder builder) { 
 this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule);
 }
 
 @Override
 public Bread bread() { 
 return provideBreadProvider.get();
 }
 
 public static final class Builder {
 private BreadModule breadModule;
 
 private Builder() { 

  19. 19. @Generated("dagger.internal.codegen.ComponentProcessor")
 public final class BreadModule_ProvideBreadFactory implements Factory<Bread> {
 private final BreadModule module;
 
 public BreadModule_ProvideBreadFactory(BreadModule module) { 
 assert module != null;
 this.module = module;
 }
 
 @Override
 public Bread get() { 
 Bread provided = module.provideBread();
 if (provided == null) {
 throw new NullPointerException("Cannot return null from a non-@Nullable @Provides m }
 return provided;
 }
 
 public static Factory<Bread> create(BreadModule module) { 
 return new BreadModule_ProvideBreadFactory(module);
 }
 }
  20. 20. @Generated("dagger.internal.codegen.ComponentProcessor")
 public final class BreadModule_ProvideBreadFactory implements Factory<Bread> {
 private final BreadModule module;
 
 public BreadModule_ProvideBreadFactory(BreadModule module) { 
 assert module != null;
 this.module = module;
 }
 
 @Override
 public Bread get() { 
 Bread provided = module.provideBread();
 if (provided == null) {
 throw new NullPointerException("Cannot return null from a non-@Nullable @Provides m }
 return provided;
 }
 
 public static Factory<Bread> create(BreadModule module) { 
 return new BreadModule_ProvideBreadFactory(module);
 }
 }
  21. 21. DaggerBreadShop::bread()
  22. 22. DaggerBreadShop::bread() BreadModule_ProvideBreadFactory::get()
  23. 23. DaggerBreadShop::bread() BreadModule_ProvideBreadFactory::get() BreadModule::provideBread()
  24. 24. DaggerBreadShop::bread() BreadModule_ProvideBreadFactory::get() BreadModule::provideBread() new Chokokorone()!!
  25. 25. Case 2 Singleton
  26. 26. @Component(modules = BreadModule.class)
 interface BreadShop {
 Bread bread();
 } @Module
 public class BreadModule {
 @Provides
 Bread provideBread() {
 return new Chokokorone();
 }
 } Before
  27. 27. @Singleton @Component(modules = BreadModule.class)
 interface BreadShop {
 Bread bread();
 } @Module
 public class BreadModule { @Singleton
 @Provides
 Bread provideBread() {
 return new Chokokorone();
 }
 } After
  28. 28. @Singleton @Component(modules = BreadModule.class)
 interface BreadShop {
 Bread bread();
 } @Module
 public class BreadModule { @Singleton
 @Provides
 Bread provideBread() {
 return new Chokokorone();
 }
 } After
  29. 29. Generated Codes • DaggerBreadShop • BreadModule_ProvideBreadFactory
  30. 30. Generated Codes • DaggerBreadShop • BreadModule_ProvideBreadFactory
  31. 31. private void initialize(final Builder builder) { 
 this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule);
 } Before
  32. 32. private void initialize(final Builder builder) { 
 this.provideBreadProvider = 
 ScopedProvider.create(
 BreadModule_ProvideBreadFactory.create(builder.breadModule)
 );
 } After
  33. 33. private void initialize(final Builder builder) { 
 this.provideBreadProvider = 
 ScopedProvider.create(
 BreadModule_ProvideBreadFactory.create(builder.breadModule)
 );
 } After
  34. 34. public final class ScopedProvider<T> implements Provider<T> { 
 : 
 @Override
 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;
 } 
 : 
 }
  35. 35. DaggerBreadShop::bread()
  36. 36. DaggerBreadShop::bread() ScopedProvider::get()
  37. 37. DaggerBreadShop::bread() ScopedProvider::get() BreadModule::provideBread()
  38. 38. DaggerBreadShop::bread() ScopedProvider::get() BreadModule::provideBread() new Chokokorone()!! (1度取得したら使い回す)
  39. 39. Case 3 Inject
  40. 40. @Component(modules = BreadModule.class)
 interface BreadShop {
 Bread bread();
 } Before
  41. 41. BreadShop shop = DaggerBreadShop
 .builder()
 .breadModule(new BreadModule())
 .build(); Bread bread = shop.bread(); Before
  42. 42. @Component(modules = BreadModule.class)
 interface BreadShop {
 void bread(Lunch lunch);
 } After public class Lunch {
 @Inject
 Bread bread;
 }
  43. 43. @Component(modules = BreadModule.class)
 interface BreadShop {
 void bread(Lunch lunch);
 } After public class Lunch {
 @Inject
 Bread bread;
 }
  44. 44. BreadShop shop = DaggerBreadShop
 .builder()
 .breadModule(new BreadModule())
 .build();
 Lunch lunch = new Lunch();
 shop.bread(lunch); // lunch.bread is Chokokorone After
  45. 45. BreadShop shop = DaggerBreadShop
 .builder()
 .breadModule(new BreadModule())
 .build();
 Lunch lunch = new Lunch();
 shop.bread(lunch); // lunch.bread is Chokokorone After
  46. 46. Generated Codes • DaggerBreadShop • BreadModule_ProvideBreadFactory • Lunch_MembersInjector
  47. 47. Generated Codes • DaggerBreadShop • BreadModule_ProvideBreadFactory • Lunch_MembersInjector
  48. 48. private void initialize(final Builder builder) { 
 this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule);
 }
 
 @Override
 public Bread bread() { 
 return provideBreadProvider.get();
 } Before
  49. 49. private void initialize(final Builder builder) { 
 this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule);
 this.lunchMembersInjector = Lunch_MembersInjector.create(provideBreadProvider);
 }
 
 @Override
 public void bread(Lunch lunch) { 
 lunchMembersInjector.injectMembers(lunch);
 } After
  50. 50. private void initialize(final Builder builder) { 
 this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule);
 this.lunchMembersInjector = Lunch_MembersInjector.create(provideBreadProvider);
 }
 
 @Override
 public void bread(Lunch lunch) { 
 lunchMembersInjector.injectMembers(lunch);
 } After
  51. 51. @Generated("dagger.internal.codegen.ComponentProcessor")
 public final class Lunch_MembersInjector implements MembersInjector<Lunch> {
 private final Provider<Bread> breadProvider;
 
 public Lunch_MembersInjector(Provider<Bread> breadProvider) { 
 assert breadProvider != null;
 this.breadProvider = breadProvider;
 }
 
 @Override
 public void injectMembers(Lunch instance) { 
 if (instance == null) {
 throw new NullPointerException("Cannot inject members into a null reference }
 instance.bread = breadProvider.get();
 }
 
 public static MembersInjector<Lunch> create(Provider<Bread> breadProvider) { 
 return new Lunch_MembersInjector(breadProvider);
 }
 }
  52. 52. @Generated("dagger.internal.codegen.ComponentProcessor")
 public final class Lunch_MembersInjector implements MembersInjector<Lunch> {
 private final Provider<Bread> breadProvider;
 
 public Lunch_MembersInjector(Provider<Bread> breadProvider) { 
 assert breadProvider != null;
 this.breadProvider = breadProvider;
 }
 
 @Override
 public void injectMembers(Lunch instance) { 
 if (instance == null) {
 throw new NullPointerException("Cannot inject members into a null reference }
 instance.bread = breadProvider.get();
 }
 
 public static MembersInjector<Lunch> create(Provider<Bread> breadProvider) { 
 return new Lunch_MembersInjector(breadProvider);
 }
 }
  53. 53. DaggerBreadShop::bread(Lunch launch)
  54. 54. DaggerBreadShop::bread(Lunch launch) Lunch_MembersInjector::injectMembers(Lunch launch)
  55. 55. DaggerBreadShop::bread(Lunch launch) Lunch_MembersInjector::injectMembers(Lunch launch) lunch = BreadModule_ProvideBreadFactory::get()
  56. 56. DaggerBreadShop::bread(Lunch launch) Lunch_MembersInjector::injectMembers(Lunch launch) lunch = BreadModule_ProvideBreadFactory::get() lunch = BreadModule::provideBread()
  57. 57. DaggerBreadShop::bread(Lunch launch) Lunch_MembersInjector::injectMembers(Lunch launch) lunch = BreadModule_ProvideBreadFactory::get() lunch = BreadModule::provideBread() lunch = new Chokokorone()!!
  58. 58. まとめ Dagger2は怖くない

×