読むと怖くないdagger2

58
読むと怖くないDagger2 kyobashi.dex #1

Upload: shinnosuke-kugimiya

Post on 19-Jan-2017

2.142 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: 読むと怖くないDagger2

読むと怖くないDagger2

kyobashi.dex #1

Page 2: 読むと怖くないDagger2

プロフィール

釘宮 愼之介 / @kgmyshin

Androidエンジニア

福岡県福岡市南区野多目出身

Page 3: 読むと怖くないDagger2

この資料の目的

Dagger2で生成されるソースを読んで、

動きを理解する

Page 4: 読むと怖くないDagger2

今回話さないこと•DIとは

•Dagger2の使い所

•どういう構成にするか

•DaggerとDagger2の違い

Page 5: 読むと怖くないDagger2

今回話すこと

ひたすら生成されたソースを見て

裏でどういう動きをするのかを見る

Page 6: 読むと怖くないDagger2

Target Annotation•Component

•Module

•Singleton

•Inject

•Scope

Page 7: 読むと怖くないDagger2

Target Annotation•Component

•Module

•Singleton

•Inject

•Scope 時間的に無理でした

Page 8: 読むと怖くないDagger2

Case 1 Minimum

Page 9: 読むと怖くないDagger2

public interface Bread {}

public class Chokokorone implements Bread {}

Page 10: 読むと怖くないDagger2

@Component(modules = BreadModule.class) interface BreadShop { Bread bread(); }

@Modulepublic class BreadModule { @Provides Bread provideBread() { return new Chokokorone(); } }

Page 11: 読むと怖くないDagger2

BreadShop shop = DaggerBreadShop .builder() .breadModule(new BreadModule()) .build();

Bread bread = shop.bread();

Page 12: 読むと怖くないDagger2

BreadShop shop = DaggerBreadShop .builder() .breadModule(new BreadModule()) .build();

Bread bread = shop.bread(); // Chokokorone

Page 13: 読むと怖くないDagger2

Generated Codes• DaggerBreadShop

• BreadModule_ProvideBreadFactory

Page 14: 読むと怖くないDagger2

@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; } }}

Page 15: 読むと怖くないDagger2

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; } }}

Page 16: 読むと怖くないDagger2

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; } }}

Page 17: 読むと怖くないDagger2

@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() { }

Page 18: 読むと怖くないDagger2

@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() { }

Page 19: 読むと怖くないDagger2

@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 method"); } return provided; } public static Factory<Bread> create(BreadModule module) { return new BreadModule_ProvideBreadFactory(module); } }

Page 20: 読むと怖くないDagger2

@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 method"); } return provided; } public static Factory<Bread> create(BreadModule module) { return new BreadModule_ProvideBreadFactory(module); }}

Page 21: 読むと怖くないDagger2

DaggerBreadShop::bread()

Page 22: 読むと怖くないDagger2

DaggerBreadShop::bread()

BreadModule_ProvideBreadFactory::get()

Page 23: 読むと怖くないDagger2

DaggerBreadShop::bread()

BreadModule_ProvideBreadFactory::get()

BreadModule::provideBread()

Page 24: 読むと怖くないDagger2

DaggerBreadShop::bread()

BreadModule_ProvideBreadFactory::get()

BreadModule::provideBread()

new Chokokorone()!!

Page 25: 読むと怖くないDagger2

Case 2 Singleton

Page 26: 読むと怖くないDagger2

@Component(modules = BreadModule.class) interface BreadShop { Bread bread(); }

@Modulepublic class BreadModule { @Provides Bread provideBread() { return new Chokokorone(); } }

Before

Page 27: 読むと怖くないDagger2

@Singleton @Component(modules = BreadModule.class) interface BreadShop { Bread bread(); }

@Modulepublic class BreadModule { @Singleton @Provides Bread provideBread() { return new Chokokorone(); } }

After

Page 28: 読むと怖くないDagger2

@Singleton @Component(modules = BreadModule.class)interface BreadShop { Bread bread();}

@Modulepublic class BreadModule { @Singleton @Provides Bread provideBread() { return new Chokokorone(); }}

After

Page 29: 読むと怖くないDagger2

Generated Codes• DaggerBreadShop

• BreadModule_ProvideBreadFactory

Page 30: 読むと怖くないDagger2

Generated Codes• DaggerBreadShop

• BreadModule_ProvideBreadFactory

Page 31: 読むと怖くないDagger2

private void initialize(final Builder builder) { this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule); }

Before

Page 32: 読むと怖くないDagger2

private void initialize(final Builder builder) { this.provideBreadProvider = ScopedProvider.create( BreadModule_ProvideBreadFactory.create(builder.breadModule) ); }

After

Page 33: 読むと怖くないDagger2

private void initialize(final Builder builder) { this.provideBreadProvider = ScopedProvider.create( BreadModule_ProvideBreadFactory.create(builder.breadModule) ); }

After

Page 34: 読むと怖くないDagger2

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; } : }

Page 35: 読むと怖くないDagger2

DaggerBreadShop::bread()

Page 36: 読むと怖くないDagger2

DaggerBreadShop::bread()

ScopedProvider::get()

Page 37: 読むと怖くないDagger2

DaggerBreadShop::bread()

ScopedProvider::get()

BreadModule::provideBread()

Page 38: 読むと怖くないDagger2

DaggerBreadShop::bread()

ScopedProvider::get()

BreadModule::provideBread()

new Chokokorone()!! (1度取得したら使い回す)

Page 39: 読むと怖くないDagger2

Case 3 Inject

Page 40: 読むと怖くないDagger2

@Component(modules = BreadModule.class) interface BreadShop { Bread bread(); }

Before

Page 41: 読むと怖くないDagger2

BreadShop shop = DaggerBreadShop .builder() .breadModule(new BreadModule()) .build();

Bread bread = shop.bread();

Before

Page 42: 読むと怖くないDagger2

@Component(modules = BreadModule.class) interface BreadShop { void bread(Lunch lunch); }

After

public class Lunch { @Inject Bread bread; }

Page 43: 読むと怖くないDagger2

@Component(modules = BreadModule.class)interface BreadShop { void bread(Lunch lunch); }

After

public class Lunch { @Inject Bread bread; }

Page 44: 読むと怖くないDagger2

BreadShop shop = DaggerBreadShop .builder() .breadModule(new BreadModule()) .build(); Lunch lunch = new Lunch(); shop.bread(lunch); // lunch.bread is Chokokorone

After

Page 45: 読むと怖くないDagger2

BreadShop shop = DaggerBreadShop .builder() .breadModule(new BreadModule()) .build();Lunch lunch = new Lunch(); shop.bread(lunch); // lunch.bread is Chokokorone

After

Page 46: 読むと怖くないDagger2

Generated Codes• DaggerBreadShop

• BreadModule_ProvideBreadFactory

• Lunch_MembersInjector

Page 47: 読むと怖くないDagger2

Generated Codes• DaggerBreadShop

• BreadModule_ProvideBreadFactory

• Lunch_MembersInjector

Page 48: 読むと怖くないDagger2

private void initialize(final Builder builder) { this.provideBreadProvider = BreadModule_ProvideBreadFactory.create(builder.breadModule); } @Override public Bread bread() { return provideBreadProvider.get(); }

Before

Page 49: 読むと怖くないDagger2

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

Page 50: 読むと怖くないDagger2

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

Page 51: 読むと怖くないDagger2

@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); } }

Page 52: 読むと怖くないDagger2

@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); }}

Page 53: 読むと怖くないDagger2

DaggerBreadShop::bread(Lunch launch)

Page 54: 読むと怖くないDagger2

DaggerBreadShop::bread(Lunch launch)

Lunch_MembersInjector::injectMembers(Lunch launch)

Page 55: 読むと怖くないDagger2

DaggerBreadShop::bread(Lunch launch)

Lunch_MembersInjector::injectMembers(Lunch launch)

lunch = BreadModule_ProvideBreadFactory::get()

Page 56: 読むと怖くないDagger2

DaggerBreadShop::bread(Lunch launch)

Lunch_MembersInjector::injectMembers(Lunch launch)

lunch = BreadModule_ProvideBreadFactory::get()

lunch = BreadModule::provideBread()

Page 57: 読むと怖くないDagger2

DaggerBreadShop::bread(Lunch launch)

Lunch_MembersInjector::injectMembers(Lunch launch)

lunch = BreadModule_ProvideBreadFactory::get()

lunch = BreadModule::provideBread()

lunch = new Chokokorone()!!

Page 58: 読むと怖くないDagger2

まとめ

Dagger2は怖くない