using and contributing to the next guice
DESCRIPTION
This overviews Guice and its successor Dagger in context of usage in NetflixOSSTRANSCRIPT
![Page 1: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/1.jpg)
Using and contributing to the next Guice
Adrian Cole@adrianfcole #netflixoss
http://www.linkedin.com/in/adrianforrestcole
![Page 2: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/2.jpg)
•Introduction
•Guice
•Guice at Netflix
•Dagger
•Dagger at Netflix
•Wrapping up
![Page 3: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/3.jpg)
Adrian• cloud guy at Netflix• founded jclouds• focus on (small) libraries
![Page 4: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/4.jpg)
thanks @jessewilson
• Guice• javax.inject• Android Core Libraries• Dagger
![Page 5: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/5.jpg)
•Introduction
•Guice
•Guice at Netflix
•Dagger
•Dagger at Netflix
•Wrapping up
![Page 6: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/6.jpg)
Wiring With Guice!
![Page 7: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/7.jpg)
(cc) creative commons from flickr.com/photos/uscpsc/7894303566/
![Page 8: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/8.jpg)
class Thermosiphon implements Pump { private final Heater heater;
Thermosiphon(Heater heater) { this.heater = heater; }
@Override public void pump() { if (heater.isHot()) { System.out.println("=> => pumping => =>"); } }}
![Page 9: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/9.jpg)
class Thermosiphon implements Pump { private final Heater heater;
@Inject Thermosiphon(Heater heater) { this.heater = heater; } ...}
Declare Dependencies
![Page 10: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/10.jpg)
class CoffeeMaker {
@Inject Heater heater; @Inject Pump pump; ...}
Declare Dependencies
![Page 11: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/11.jpg)
class DripCoffeeModule extends AbstractModule {
@Overrides void configure() { bind(Heater.class).to(ElectricHeater.class);
bind(Pump.class).to(Thermosiphon.class); }}
Satisfy Dependencies
![Page 12: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/12.jpg)
class CoffeeApp {
public static void main(String[] args) {
Injector injector
= Guice.createInjector(new
DripCoffeeModule());
CoffeeMaker coffeeMaker
= injector.getInstance(CoffeeMaker.class);
coffeeMaker.brew(); }
}
Build the Injector
![Page 13: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/13.jpg)
•Introduction
•Guice
•Guice at Netflix
•Dagger
•Dagger at Netflix
•Wrapping up
![Page 14: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/14.jpg)
Netflix uses lots of Guice• Governator– Governate (verb) to wire together an app so that
it implicitly bootstraps and exposes its lifecycle.
• Karyon– Karyonate (verb) unpronouncable… so– Blueprint for a web app or REST service
![Page 15: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/15.jpg)
Governator Bootstrap
• Extends Guice– classpath scanning and automatic binding– lifecycle management– configuration to field mapping– field validation– parallelized object warmup
• Some overlap with Apache Onami
![Page 16: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/16.jpg)
class DieselHeater implements Heater {
...
@PostConstruct void startEngine() {
// mmm… exhaust with coffee.. }}
Define @PostConstruct
![Page 17: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/17.jpg)
class CoffeeApp {
public static void main(String[] args) {
Injector injector
= LifeCycleInjector.createInjector(new
DripCoffeeModule());
CoffeeMaker coffeeMaker
= injector.getInstance(CoffeeMaker.class);
coffeeMaker.brew(); }
}
Build the Injector
![Page 18: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/18.jpg)
Karyon• Web Service Blueprint– Extends Governator, Guice Servlet– Built-in Admin Console– Pluggable Web Resources– Cloud-Ready hooks
@Application has @Components Usually has a HealthCheckHandler
![Page 19: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/19.jpg)
@Component(disableProperty = “killswitch”)class DieselHeater implements Heater {
...
@PostConstruct void startEngine() {
// mmm… exhaust with coffee.. }}
Define @Component
![Page 20: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/20.jpg)
appName.properties com.netflix.karyon.server.base.packages= com.foo.appName.components
Check config
![Page 21: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/21.jpg)
A Cloud Native Open Source Platform
@adrianfcole #netflixoss
More?
![Page 22: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/22.jpg)
•Introduction
•Guice
•Guice at Netflix
•Dagger
•Dagger at Netflix
•Wrapping up
![Page 23: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/23.jpg)
Dagger
Slides by Jesse Wilson from Square
A fast dependency injector for Android and Java.
![Page 24: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/24.jpg)
•Dagger
–Motivation
–Using Dagger
–Inside Dagger
![Page 25: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/25.jpg)
Motivation for Dependency Injection
• Decouple concrete from concrete• Uniformity
![Page 26: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/26.jpg)
Dependency InjectionChoices
• PicoContainer• Spring• Guice• javax.inject
![Page 27: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/27.jpg)
(cc) creative commons from flickr.com/photos/getbutterfly/6317955134/
![Page 28: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/28.jpg)
(cc) creative commons from flickr.com/photos/wikidave/2988710537/
![Page 29: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/29.jpg)
We still love you, Froyo
• Eager vs. lazy graph construction• Reflection vs. codegen
![Page 30: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/30.jpg)
typicalprogrammer.com/?p=143
“I didn’t really expect anyone to use [git] because it’s so hard to use, but that turns out to be its big appeal.
No technology can ever be too arcane or complicated for the black t-shirt crowd.”
–Linus Torvalds
![Page 31: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/31.jpg)
No black t-shirt necessary
![Page 32: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/32.jpg)
(cc) creative commons from flickr.com/photos/mike_miley/5969110684/
![Page 33: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/33.jpg)
• Know everything at build time.
• Easy to see how dependencies are used & satisfied
![Page 34: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/34.jpg)
Motivation for Dagger
• It's like Guice, but with speed instead of features
• Simple• Predictable
also...
![Page 35: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/35.jpg)
•Dagger
–Motivation
–Using Dagger
–Inside Dagger
![Page 36: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/36.jpg)
DirectedAcyclicGraph
DAGger.
![Page 37: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/37.jpg)
(cc) creative commons from flickr.com/photos/uscpsc/7894303566/
![Page 38: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/38.jpg)
class Thermosiphon implements Pump { private final Heater heater;
Thermosiphon(Heater heater) { this.heater = heater; }
@Override public void pump() { if (heater.isHot()) { System.out.println("=> => pumping => =>"); } }}
![Page 39: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/39.jpg)
class Thermosiphon implements Pump { private final Heater heater;
@Inject Thermosiphon(Heater heater) { this.heater = heater; } ...}
Declare Dependencies
![Page 40: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/40.jpg)
class CoffeeMaker {
@Inject Heater heater; @Inject Pump pump; ...}
Declare Dependencies
![Page 41: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/41.jpg)
@Module(injects = CoffeeMakerApp.java)class DripCoffeeModule {
@Provides Heater provideHeater() { return new ElectricHeater(); }
@Provides Pump providePump(Thermosiphon pump) { return pump; }}
Satisfy Dependencies
![Page 42: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/42.jpg)
class CoffeeApp {
public static void main(String[] args) {
ObjectGraph objectGraph
= ObjectGraph.create(new DripCoffeeModule());
CoffeeMaker coffeeMaker
= objectGraph.get(CoffeeMaker.class);
coffeeMaker.brew(); }
}
Build the Graph
![Page 43: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/43.jpg)
Neat features
• Lazy<T>• Module overrides• Multibindings
![Page 44: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/44.jpg)
class GridingCoffeeMaker {
@Inject Lazy<Grinder> lazyGrinder;
public void brew() {
while (needsGrinding()) { // Grinder created once and cached.
Grinder grinder = lazyGrinder.get()
grinder.grind(); } }}
Lazy<T>
![Page 45: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/45.jpg)
@Module( includes = DripCoffeeModule.class,
injects = CoffeeMakerTest.class,
overrides = true ) static class TestModule {
@Provides @Singleton Heater provideHeater() { return Mockito.mock(Heater.class); }
}
Module Overrides
![Page 46: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/46.jpg)
@Moduleclass TwitterModule { @Provides(type=SET) SocialApi provideApi() { ... }}@Moduleclass GooglePlusModule { @Provides(type=SET) SocialApi provideApi() { ... }}...@Inject Set<SocialApi>
Multibindings
![Page 47: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/47.jpg)
•Dagger
–Motivation
–Using Dagger
–Inside Dagger
![Page 48: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/48.jpg)
Graphs!
![Page 49: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/49.jpg)
Creating Graphs
• Compile time– annotation processor
• Runtime– generated code loader– reflection
![Page 50: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/50.jpg)
Using Graphs
• Injection• Validation• Graphviz!
![Page 51: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/51.jpg)
But how?
• Bindings have names like“com.squareup.geo.LocationMonitor”
• Bindings know the names of their dependencies, like“com.squareup.otto.Bus”
![Page 52: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/52.jpg)
final class CoffeeMaker$InjectAdapter extends Binding<CoffeeMaker> {
private Binding<Heater> f0; private Binding<Pump> f1;
public CoffeeMaker$InjectAdapter() { super("coffee.CoffeeMaker", ...); }
public void attach(Linker linker) { f0 = linker.requestBinding("coffee.Heater", coffee.CoffeeMaker.class); f1 = linker.requestBinding("coffee.Pump", coffee.CoffeeMaker.class); }
public CoffeeMaker get() { coffee.CoffeeMaker result = new coffee.CoffeeMaker(); injectMembers(result); return result; }
public void injectMembers(CoffeeMaker object) { object.heater = f0.get(); object.pump = f1.get(); }
public void getDependencies(Set<Binding<?>> bindings) { bindings.add(f0); bindings.add(f1); }
}
![Page 53: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/53.jpg)
Validation
• Eager at build time• Lazy at runtime
![Page 54: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/54.jpg)
dagger-compiler
(cc) creative commons from flickr.com/photos/discover-central-california/8010906617
![Page 55: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/55.jpg)
Built into javac
Foolishly easy to use. Just put dagger-compiler on your classpath!
javax.annotation.processing
![Page 56: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/56.jpg)
It’s a hassle(for us)
• Coping with prebuilt .jar files• Versioning• Testing
![Page 57: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/57.jpg)
... and it’s limited(for you)
• No private or final field access• Incremental builds are imperfect• ProGuard
![Page 58: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/58.jpg)
... but it’s smoking fast!(for your users)
• Startup time for Square Wallet on one device improved from ~5 seconds to ~2 seconds
![Page 59: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/59.jpg)
Different Platforms are Different
• HotSpot• Android• GWT
![Page 60: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/60.jpg)
HotSpot:Java on the Server
• The JVM is fast• Code bases are huge
![Page 61: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/61.jpg)
Android
• Battery powered• Garbage collection causes jank• Slow reflection, especially on older devices• Managed lifecycle
![Page 62: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/62.jpg)
GWT• Code size really matters• Compiler does full-app optimizations• No reflection.
github.com/tbroyer/sheath
![Page 63: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/63.jpg)
API Designin the GitHub age
Forking makes it easy to stay small & focused
![Page 64: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/64.jpg)
public @interface Inject {}
public @interface Named { String value() default "";}
public interface Provider { T get();}public @interface Qualifier {}public @interface Scope {}public @interface Singleton {}
javax.inject
![Page 65: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/65.jpg)
public interface Lazy<T> {
T get();}
public interface MembersInjector<T> {
void injectMembers(T instance);}
public final class ObjectGraph {
public static ObjectGraph create(Object... modules);
public ObjectGraph plus(Object... modules);
public void validate();
public void injectStatics();
public <T> T get(Class type);
public <T> T inject(T instance);}
public @interface Module {
Class[] injects() default { }; Class[] staticInjections() default { }; Class[] includes() default { }; Class addsTo() default Void.class; boolean overrides() default false; boolean complete() default true; boolean library() default true;}
public @interface Provides {
enum Type { UNIQUE, SET }
Type type() default Type.UNIQUE;}
dagger
![Page 66: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/66.jpg)
•Introduction
•Guice
•Guice at Netflix
•Dagger
•Dagger at Netflix
•Wrapping up
![Page 67: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/67.jpg)
PORTABLE CONTROL OF DNS CLOUDS
![Page 68: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/68.jpg)
@Provides @SingletonRoute53 route53(Feign feign, Route53Target target) {
return feign.newInstance(target);}
Dependencies are HTTP Targets
![Page 69: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/69.jpg)
Portable implementations
class Route53ZoneApi implements ZoneApi {
@Inject Route53 route53; ...}
![Page 70: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/70.jpg)
•Introduction
•Guice
•Guice at Netflix
•Dagger
•Dagger at Netflix
•Wrapping up
![Page 71: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/71.jpg)
• Still the best choice for many apps• Broad ecosystem and stable core• May soon be able to mix & match with
Dagger
Guice
![Page 72: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/72.jpg)
• Great for libraries• Extension averse, feature conservative• Friendly forks
Dagger
![Page 73: Using and contributing to the next Guice](https://reader035.vdocuments.net/reader035/viewer/2022062220/5564b0d0d8b42a98268b4e8b/html5/thumbnails/73.jpg)
Takeaway
Dagger is a leaner version of Guice, suitable for libraries.
Fork-friendly doesn’t mean don’t collaborate.
http://square.github.io/dagger/https://groups.google.com/forum/#!forum/dagger-discuss
http://www.linkedin.com/in/adrianforrestcole@adrianfcole #netflixoss