This document discusses dependency injection frameworks Guice and Dagger. It provides an overview of how Netflix uses Guice for projects like Governator and Karyon. It also explains how Dagger works by generating code at compile time to create a dependency injection graph, allowing for faster initialization than reflection-based frameworks. Examples are given of how to declare dependencies and satisfy them in both Guice and Dagger.
14. 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
15. 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
16. class DieselHeater implements Heater {
...
@PostConstruct void startEngine() {
// mmm… exhaust with coffee..
}
}
Define
@PostConstruct
17. 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
18. 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
29. We still love you, Froyo
• Eager vs. lazy graph construction
• Reflection vs. codegen
30. 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
44. class GridingCoffeeMaker {
@Inject Lazy<Grinder> lazyGrinder;
public void brew() {
while (needsGrinding()) {
// Grinder created once and cached.
Grinder grinder = lazyGrinder.get()
grinder.grind();
}
}
}
Lazy<T>
51. But how?
• Bindings have names like
“com.squareup.geo.LocationMonitor”
• Bindings know the names of their
dependencies, like
“com.squareup.otto.Bus”
52. 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); }
}
61. Android
• Battery powered
• Garbage collection causes jank
• Slow reflection, especially on older devices
• Managed lifecycle
62. GWT
• Code size really matters
• Compiler does full-app optimizations
• No reflection.
github.com/tbroyer/sheath
63. API Design
in the GitHub age
Forking makes it easy to stay small & focused
64. 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
65. 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
71. • Still the best choice for many apps
• Broad ecosystem and stable core
• May soon be able to mix & match with
Dagger
Guice
72. • Great for libraries
• Extension averse, feature conservative
• Friendly forks
Dagger
73. 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
Notas do Editor
Resources such as JSR-311 and JerseyHooks like Service Registration and Discovery, HealthCheck hooks etc