Devoxx Dagger2.ForExport PDF
Devoxx Dagger2.ForExport PDF
Dagger 2
Jake Wharton
Dependency Injection
flickr.com/photos/sunsetnoir/6984108500
Dependency Injection
• No “new”, dependencies come to you
flickr.com/photos/sunsetnoir/6984108500
Dependency Injection
• First and foremost a pattern
Dependency Injection
• First and foremost a pattern
Tweeter
Dependency Injection
• First and foremost a pattern
Tweeter
Tweeter
Dependency Injection
• How do we avoid the boilerplate that comes with the pattern?
Tweeter
Tweeter
Library Rescue
• Spring • Others…
• Guice
• Dagger (v1)
• PicoContainer
• CDI
Guice Dagger
(v1)
Guice
Guice
• Developed at Google by Bob Lee, later Jesse Wilson, others.
Guice
• Developed at Google by Bob Lee, later Jesse Wilson, others.
NetworkModule#provideTwitterApi
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
TwitterApi NetworkModule#provideTwitterApi
Providing Dependencies
• Modules are classes whose methods provide dependencies.
TwitterApi NetworkModule#provideTwitterApi
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
TwitterModule#provideTweeter
TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Providing Dependencies
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
Requesting Dependencies
Requesting Dependencies
• @Inject annotation required.
Requesting Dependencies
• @Inject annotation required.
}
!public class TwitterApplication {
! private final Tweeter tweeter;
! private final Timeline timeline;
!
! @Inject
! public TwitterApplication(Tweeter tweeter, Timeline timeline) {
! this.tweeter = tweeter;
! this.timeline = timeline;
! }
!
@Inject
public void enableStreaming(Streaming streaming) {
streaming.register(this);
}
}
!public class TwitterApplication {
! private final Tweeter tweeter;
! private final Timeline timeline;
!
! @Inject
! public TwitterApplication(Tweeter tweeter, Timeline timeline) {
! this.tweeter = tweeter;
! this.timeline = timeline;
! }
!
@Inject
public void enableStreaming(Streaming streaming) {
streaming.register(this);
}
}
Field Injection
Field Injection
• @Inject on fields for dependencies.
Field Injection
• @Inject on fields for dependencies.
• The injector.
@Component
!
public interface TwitterComponent {
}
@Component(modules = {
NetworkModule.class,
TwitterModule.class,
})
!
public interface TwitterComponent {
}
@Singleton
@Component(modules = {
NetworkModule.class,
TwitterModule.class,
!})
public interface TwitterComponent {
}
@Singleton
@Component (modules = {
NetworkModule.class,
TwitterModule.class,
!})
public
interface TwitterComponent {
Tweeter tweeter();
Timeline timeline();
}
TwitterComponent component = Dagger_TwitterComponent.builder()
.networkModule(new NetworkModule())
.twitterModule(new TwitterModule("JakeWharton"))
.build();
!TwitterComponentcomponent = Dagger_TwitterComponent.builder()
! .networkModule(new NetworkModule())
! .twitterModule(new TwitterModule("JakeWharton"))
! .build();
!
Tweeter
! tweeter = component.tweeter();
Timeline timeline = component.timeline();
TwitterComponent component = Dagger_TwitterComponent.builder()
.networkModule(new NetworkModule())
.twitterModule(new TwitterModule("JakeWharton"))
.build();
!
!Tweetertweeter = component.tweeter();
Timeline timeline = component.timeline();
TwitterComponent component = Dagger_TwitterComponent.builder()
.twitterModule(new TwitterModule("JakeWharton"))
.build();
!
!Tweetertweeter = component.tweeter();
Timeline timeline = component.timeline();
TwitterComponent component = Dagger_TwitterComponent.builder()
.twitterModule(new TwitterModule("JakeWharton"))
.build();
!
Tweeter tweeter = component.tweeter();
tweeter.tweet("Hello,
!
#Devoxx 2014!");
!
Timeline timeline = component.timeline();
timeline.loadMore(20);
for (Tweet tweet : timeline.get()) {
System.out.println(tweet);
}
public class TwitterApplication implements Runnable {
private final Tweeter tweeter;
private final Timeline timeline;
@Inject
public TwitterApplication(Tweeter tweeter, Timeline timeline) {
this.tweeter = tweeter;
this.timeline = timeline;
}
@Override public void run() {
tweeter.tweet("Hello #Devoxx 2014!");
timeline.loadMore(20);
for (Tweet tweet : timeline.get()) {
System.out.println(tweet);
}
}
}
@Singleton
@Component(modules = {
NetworkModule.class,
TwitterModule.class,
})
interface TwitterComponent {
TwitterApplication app();
}
@Singleton
@Component(modules = {
NetworkModule.class,
TwitterModule.class,
})
interface TwitterComponent {
TwitterApplication app();
}
• The injector.
Components
• Bridge between modules and injection.
• The injector.
• Implementation of scopes.
@Singleton
@Component(modules = NetworkModule.class)
public interface ApiComponent {
}
@Singleton
@Component(modules = NetworkModule.class)
public interface ApiComponent {
}
@Component(
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
@Singleton
@Component(modules = NetworkModule.class)
public interface ApiComponent {
}
@Component(
dependencies = ApiComponent.class,
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
@Singleton
@Component(modules = NetworkModule.class)
public interface ApiComponent {
TwitterApi api();
}
@Component(
dependencies = ApiComponent.class,
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
@Singleton
@Component(modules = NetworkModule.class)
public interface ApiComponent {
TwitterApi api();
}
@Singleton
@Component(
dependencies = ApiComponent.class,
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
@Singleton
@Component(modules = NetworkModule.class)
public interface ApiComponent {
TwitterApi api();
}
@Singleton
@Component(
dependencies = ApiComponent.class,
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
@Singleton
@Component(modules = NetworkModule.class)
public interface ApiComponent {
TwitterApi api();
}
@Component(
dependencies = ApiComponent.class,
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
@Module
public class TwitterModule {
private final String user;
public TwitterModule(String user) {
this.user = user;
}
@Provides @Singleton
Tweeter provideTweeter(TwitterApi api) {
return new Tweeter(api, user);
}
@Provides @Singleton
Timeline provideTimeline(TwitterApi api) {
return new Timeline(api, user);
}
}
@Module
public class TwitterModule {
private final String user;
public TwitterModule(String user) {
this.user = user;
}
@Provides @Singleton
Tweeter provideTweeter(TwitterApi api) {
return new Tweeter(api, user);
}
@Provides @Singleton
Timeline provideTimeline(TwitterApi api) {
return new Timeline(api, user);
}
}
@Module
public class TwitterModule {
private final String user;
public TwitterModule(String user) {
this.user = user;
}
@Provides
Tweeter provideTweeter(TwitterApi api) {
return new Tweeter(api, user);
}
@Provides
Timeline provideTimeline(TwitterApi api) {
return new Timeline(api, user);
}
}
ApiComponent apiComponent = Dagger_ApiComponent.builder().build();
ApiComponent apiComponent = Dagger_ApiComponent.create();
ApiComponent apiComponent = Dagger_ApiComponent.create();
ApiComponent apiComponent = Dagger_ApiComponent.create();
component.app().run();
Scope Annotations
Scope Annotations
• Only create a single instance.
Scope Annotations
• Only create a single instance.
@Scope
public @interface User {
}
@Module
public class TwitterModule {
private final String user;
public TwitterModule(String user) {
this.user = user;
}
@Provides
Tweeter provideTweeter(TwitterApi api) {
return new Tweeter(api, user);
}
@Provides
Timeline provideTimeline(TwitterApi api) {
return new Timeline(api, user);
}
}
@Module
public class TwitterModule {
private final String user;
public TwitterModule(String user) {
this.user = user;
}
@Provides @User
@Provides
Tweeter provideTweeter(TwitterApi api) {
return new Tweeter(api, user);
}
@Provides @User
@Provides
Timeline provideTimeline(TwitterApi api) {
return new Timeline(api, user);
}
}
@Component(
dependencies = ApiComponent.class,
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
@User
@Component(
dependencies = ApiComponent.class,
modules = TwitterModule.class
)
public interface TwitterComponent {
TwitterApplication app();
}
NetworkModule
OkHttpClient
TwitterApi
ApiComponent
NetworkModule
OkHttpClient
TwitterApi
ApiComponent
NetworkModule
OkHttpClient
TwitterApi
ApiComponent
NetworkModule
OkHttpClient TwitterApi
TwitterApi
ApiComponent
NetworkModule
OkHttpClient TwitterApi
TwitterApi
ApiComponent
NetworkModule TwitterModule
TwitterApi Timeline
TwitterComponent
ApiComponent
NetworkModule TwitterModule
TwitterApi Timeline
TwitterComponent
ApiComponent
NetworkModule TwitterModule
TwitterApi Timeline
TwitterComponent
ApiComponent
NetworkModule TwitterModule
TwitterApi Timeline
TwitterComponent
ApiComponent
NetworkModule TwitterModule
TwitterApi Timeline
TwitterComponent
ApiComponent
NetworkModule TwitterModule
TwitterApi Timeline
ApiComponent
NetworkModule
OkHttpClient TwitterApi
TwitterApi
TwitterComponent
ApiComponent
NetworkModule TwitterModule
TwitterApi Timeline
Under The Hood
Under The Hood
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter TwitterModule#provideTweeter
Timeline TwitterModule#provideTimeline
@Module
public class NetworkModule {
@Provides @Singleton
OkHttpClient provideOkHttpClient() {
return new OkHttpClient();
}
@Provides @Singleton
TwitterApi provideTwitterApi(OkHttpClient client) {
return new TwitterApi(client);
}
}
public class NetworkModule {
OkHttpClient provideOkHttpClient() {}
TwitterApi provideTwitterApi(OkHttpClient) {}
}
}
interface ApiComponent {
TwitterApi api();
}
Dagger_TwitterComponent.builder()...build()
Dagger_ApiComponent.create()
new NetworkModule
new NetworkModule_ProvideOkHttpClientFactory
new NetworkModule_ProvideTwitterApiFactory
Dagger_TwitterComponent.builder()...build()
new Factory<TwitterApi>
Dagger_ApiComponent.create()
new NetworkModule
new NetworkModule_ProvideOkHttpClientFactory
new NetworkModule_ProvideTwitterApiFactory
Dagger_TwitterComponent.builder()...build()
new Factory<TwitterApi>
new TwitterModule_ProvideTweeterFactory
new TwitterModule_ProvideTimelineFactory
new TwitterApplication_Factory
twitterComponent.app()
twitterComponent.app()
twitterApplicationProvider.get()
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient()
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..)
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterModule.provideTweeter(..)
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterModule.provideTweeter(..) new Tweeter(..)
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterModule.provideTweeter(..) new Tweeter(..)
timelineProvider.get()
apiProvider.get()
apiComponent.api()
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterModule.provideTweeter(..) new Tweeter(..)
timelineProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterModule.provideTweeter(..) new Tweeter(..)
timelineProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
twitterModule.provideTimeline(..)
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterModule.provideTweeter(..) new Tweeter(..)
timelineProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
twitterModule.provideTimeline(..) new Timeline(..)
twitterComponent.app()
twitterApplicationProvider.get()
tweeterProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
clientProvider.get()
networkModule.provideOkHttpClient() new OkHttpClient()
networkModule.provideTwitterApi(..) new TwitterApi(..)
twitterModule.provideTweeter(..) new Tweeter(..)
timelineProvider.get()
apiProvider.get()
apiComponent.api()
provideTwitterApiProvider.get()
twitterModule.provideTimeline(..) new Timeline(..)
new TwitterApplication(..)
Annotation Processing
Annotation Processing
bit.ly/apt-bd
JSR 330
public @interface Inject {}
JSR 330 }
T get();
Dagger 1
boolean overrides() default false;
boolean complete() default true;
boolean library() default true;
}
Dagger 1
boolean overrides() default false;
boolean complete() default true;
boolean library() default true;
}
• Asynchronous producers.
More Concepts
• Set and map bindings.
• Asynchronous producers.
• Asynchronous producers.