introduction to google guice: programming is fun again!€¦ · overview > motivation • ugh,...

84
Introduction to Google Guice: Programming is fun again! Jesse Wilson Google, Inc. http://code.google.com/p/google-guice/ Friday, June 5, 2009

Upload: others

Post on 04-Jul-2020

17 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Introduction to Google Guice: Programming is fun again!

Jesse WilsonGoogle, Inc.http://code.google.com/p/google-guice/

Friday, June 5, 2009

Page 2: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

What youʼll get out of this talkDependency Injection and Guice> Objects come to you

• Instead of ʻnewʼ and factories> Reusable modules> First-class scopes> Easier tests

• and more confidence> Less boilerplate

2photo courtesy of http://flickr.com/photos/xero79/378837837

Friday, June 5, 2009

Page 3: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Overview

> Motivation• Ugh, factories arenʼt fun

> Using Guice• @Inject is the new new

> Leveraging Guice• A tour of extensions and advanced features

3

Friday, June 5, 2009

Page 4: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Exampletweet tweet

4

> Setting the stage> Constructors> Factories> Dependency Injection

• by hand• with Guice

photo courtesy ofhttp://flickr.com/photos/jessicafm/62271212

Friday, June 5, 2009

Page 5: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Code you might writeA tweets client public void postButtonClicked() {

String text = textField.getText();

if (text.length() > 140) {

Shortener shortener = new TinyUrlShortener();

text = shortener.shorten(text);

}

if (text.length() <= 140) {

Tweeter tweeter = new SmsTweeter();

tweeter.send(text);

textField.clear();

}

}

5

Friday, June 5, 2009

Page 6: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Calling Dependenciesʼ Constructors Directly

photo courtesy of http://flickr.com/photos/salford_ian/3134250986Friday, June 5, 2009

Page 7: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public void postButtonClicked() {

String text = textField.getText();

if (text.length() > 140) {

Shortener shortener = new TinyUrlShortener();

text = shortener.shorten(text);

}

if (text.length() <= 140) {

Tweeter tweeter = new SmsTweeter();

tweeter.send(text);

textField.clear();

}

}

Getting dependencies via their constructors...calling new directly doesnʼt afford testing

7

We post to tinyurl.com and send an SMS for each test! This is neither fast nor reliable.

Friday, June 5, 2009

Page 8: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public void postButtonClicked() {

String text = textField.getText();

if (text.length() > 140) {

Shortener shortener = new TinyUrlShortener();

text = shortener.shorten(text);

}

if (text.length() <= 140) {

Tweeter tweeter = new SmsTweeter();

tweeter.send(text);

textField.clear();

}

}

Getting dependencies via their constructors...calling new directly doesnʼt afford testing

7

We post to tinyurl.com and send an SMS for each test! This is neither fast nor reliable.

Friday, June 5, 2009

Page 9: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Getting Dependencies from Factories

photo courtesy of http://flickr.com/photos/abulic_monkey/130899453Friday, June 5, 2009

Page 10: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public void postButtonClicked() {

String text = textField.getText();

if (text.length() > 140) {

Shortener shortener = ShortenerFactory.get();

text = shortener.shorten(text);

}

if (text.length() <= 140) {

Tweeter tweeter = TweeterFactory.get();

tweeter.send(text);

textField.clear();

}

}

Getting dependencies from factories

9

Friday, June 5, 2009

Page 11: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Implementing the factoryall of this boilerplate slows you down. Ugh!

10

We still have to write a factory for the URL shortener.

Friday, June 5, 2009

Page 12: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public class TweeterFactory {

private static Tweeter testValue;

public static Tweeter get() {

if (testValue != null) {

return testValue;

}

return new SmsTweeter();

}

public static void setForTesting(Tweeter tweeter) {

testValue = tweeter;

}

}

Implementing the factoryall of this boilerplate slows you down. Ugh!

10

We still have to write a factory for the URL shortener.

Friday, June 5, 2009

Page 13: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Factory dependency graphthe static dependency causes monolithic compiles...

11

TweetClient

TweeterFactory

SmsTweeter

depends

depends

Friday, June 5, 2009

Page 14: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

11

TweetClient

TweeterFactory

SmsTweeter ShortenerFactory

TinyUrlShortenerAndroidSms

LoginStoreFactory

LoginStore

CryptoFactory DataFactory

Md5Crypto SqlDataSoapConnection

TagParserFactory

RegexTagParser

SQLite

SoapConnectionFactory

HttpConnectionDomParserFactory

Friday, June 5, 2009

Page 15: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public void testSendTweet() {

MockTweeter tweeter = new MockTweeter();

TweeterFactory.setForTesting(tweeter);

}

TweetClient tweetClient = new TweetClient();

tweetClient.getEditor().setText("Hello!");

tweetClient.postButtonClicked();

assertEquals("Hello!", tweeter.getSent());

Testing with a factoryitʼs testable

12

Friday, June 5, 2009

Page 16: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public void testSendTweet() {

MockTweeter tweeter = new MockTweeter();

TweeterFactory.setForTesting(tweeter);

}

TweeterFactory.setForTesting(null);

TweetClient tweetClient = new TweetClient();

tweetClient.getEditor().setText("Hello!");

tweetClient.postButtonClicked();

assertEquals("Hello!", tweeter.getSent());

Testing with a factoryitʼs testable

12

...but donʼt forget to clean up

Friday, June 5, 2009

Page 17: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public void testSendTweet() {

MockTweeter tweeter = new MockTweeter();

TweeterFactory.setForTesting(tweeter);

}

try {

} finally {

}

TweeterFactory.setForTesting(null);

TweetClient tweetClient = new TweetClient();

tweetClient.getEditor().setText("Hello!");

tweetClient.postButtonClicked();

assertEquals("Hello!", tweeter.getSent());

Testing with a factoryitʼs testable

12

...but donʼt forget to clean up ...properly!

Friday, June 5, 2009

Page 18: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Dependency Injection (DI) by hand

photo courtesy of http://flickr.com/photos/dan4th/1657850829Friday, June 5, 2009

Page 19: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public class TweetClient {

private final Shortener shortener; private final Tweeter tweeter;

public TweetClient(Shortener shortener, Tweeter tweeter) { this.shortener = shortener; this.tweeter = tweeter; }

public void postButtonClicked() {

...

if (text.length() <= 140) {

tweeter.send(text);

textField.clear();

}

Dependency injection by handobjects come to you

14

Dependency Injection:rather than looking it up, get it passed in.

Friday, June 5, 2009

Page 20: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public void testSendTweet() {

MockShortener shortener = new MockShortener();

MockTweeter tweeter = new MockTweeter();

TweetClient tweetClient

= new TweetClient(shortener, tweeter);

tweetClient.getEditor().setText("Hello!");

tweetClient.postButtonClicked();

assertEquals("Hello!", tweeter.getSent());

}

Testing with dependency injectionno cleanup required

15

Friday, June 5, 2009

Page 21: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public class TweetClientFactory {

private static TweetClient testValue;

public static TweetClient get() {

if (testValue != null) {

return testValue;

}

Shortener shortener = ShortenerFactory.get();

Tweeter tweeter = TweeterFactory.get();

return new TweetClient(shortener, tweeter);

}

Where does the dependency go?ugh, you still have to write boilerplate code to build stuff

16

DI motto:Push dependencies from the core to the edges

Friday, June 5, 2009

Page 22: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Where does the dependency go?your application code sheds its heavyweight dependencies

17

TweetClient

SmsTweeterTinyUrlShortener

depends

creates

TweeterFactoryShortenerFactory

depends

TweetClientFactory

TweeterShortener

depends

Friday, June 5, 2009

Page 23: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Dependency Injection with Guice

photo courtesy of http://flickr.com/photos/randysonofrobert/347327376Friday, June 5, 2009

Page 24: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Dependency injection with Guice

19

TweetClient

SmsTweeterTinyUrlShortener

depends

creates

depends

TweeterShortener

depends

TweeterFactoryShortenerFactory

TweetClientFactory

Friday, June 5, 2009

Page 25: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Dependency injection with Guice

19

TweetClient

SmsTweeterTinyUrlShortener

depends

creates

depends

TweetModule

Injector

TweeterShortener

depends

Friday, June 5, 2009

Page 26: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

import com.google.inject.AbstractModule;

public class TweetModule extends AbstractModule {

protected void configure() {

}

}

Configuring the injector using modules

20

Friday, June 5, 2009

Page 27: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

import com.google.inject.AbstractModule;

public class TweetModule extends AbstractModule {

protected void configure() {

}

}

Configuring the injector using modules

20

bind(Tweeter.class) .to(SmsTweeter.class);

bind(Shortener.class) .to(TinyUrlShortener.class);

Friday, June 5, 2009

Page 28: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

import com.google.inject.Inject;

public class TweetClient {

private final Shortener shortener;

private final Tweeter tweeter;

public TweetClient(Shortener shortener, Tweeter tweeter) {

this.shortener = shortener;

this.tweeter = tweeter;

}

Telling Guice to use your constructorannotate a constructor with @Inject

21

Friday, June 5, 2009

Page 29: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

import com.google.inject.Inject;

public class TweetClient {

private final Shortener shortener;

private final Tweeter tweeter;

public TweetClient(Shortener shortener, Tweeter tweeter) {

this.shortener = shortener;

this.tweeter = tweeter;

}

Telling Guice to use your constructorannotate a constructor with @Inject

21

@Inject

Friday, June 5, 2009

Page 30: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

public static void main(String[] args) {

Injector injector = Guice.createInjector(new TweetModule());

TweetClient tweetClient = injector.getInstance(TweetClient.class);

tweetClient.show();

}

Bootstrapping Guice

22

Friday, June 5, 2009

Page 31: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Using Guice

> Why?> Bindings> Scopes> Injections

23photo courtesy of http://flickr.com/photos/theogeo/2211326536

Friday, June 5, 2009

Page 32: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Why use Guice?

> Writing boilerplate slows you down> More up front type checking> It makes it easier to write better code

> Plus...• Scopes• AOP• Tight integration with web, data access APIs, etc.

24

Friday, June 5, 2009

Page 33: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Guice in a nutshell

> Classes have dependencies• these are passed in automatically• identified by annotations

> Modules define how dependencies are resolved

25

Friday, June 5, 2009

Page 34: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Bindings

photo courtesy of http://flickr.com/photos/uwehermann/3417729678Friday, June 5, 2009

Page 35: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Bindingsmap types to their implementations

27

public class TweetModule extends AbstractModule {

protected void configure() {

bind(TweetClient.class);

bind(Tweeter.class) .to(SmsTweeter.class);

bind(String.class).annotatedWith(Username.class) .toInstance("jesse");

}

@Provides Shortener provideShortener() {

return new TinyUrlShortener();

}

}

Friday, June 5, 2009

Page 36: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Constructor Bindingsto resolve a type, call its constructor

28

new TweetClient(...)TweetClient

Friday, June 5, 2009

Page 37: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Constructor Bindingsto resolve a type, call its constructor

28

public class TweetModule extends AbstractModule {

protected void configure() {

bind(TweetClient.class);

}

}

new TweetClient(...)TweetClient

> Requires @Inject on the constructor• Dependencies are passed in as parameters

Friday, June 5, 2009

Page 38: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Provider methodsto resolve a type, call this method

29

provideShortener(...)Shortener

Friday, June 5, 2009

Page 39: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Provider methodsto resolve a type, call this method

29

public class TweetModule extends AbstractModule {

protected void configure() {...}

@Provides Shortener provideShortener() {

return new TinyUrlShortener();

}

}

provideShortener(...)Shortener

> Annotate a module method with @Provides• The return type is bound• Dependencies are passed in as parameters

Friday, June 5, 2009

Page 40: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Linked Bindingsto resolve a type, use another binding

30

SmsTweeterTweeter

Friday, June 5, 2009

Page 41: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Linked Bindingsto resolve a type, use another binding

30

public class TweetModule extends AbstractModule {

protected void configure() {

bind(Tweeter.class).to(SmsTweeter.class);

}

}

> Requires a binding for the target type• If none exists, one will be created automatically

SmsTweeterTweeter

Friday, June 5, 2009

Page 42: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Linked Bindingsto resolve a type, use another binding

31

public class TweetModule extends AbstractModule {

protected void configure() {

bind(Tweeter.class).to(SmsTweeter.class);

}

}

new SmsTweeter(...)Tweeter

> Requires a binding for the target type• If none exists, one may be created automatically...

SmsTweeter

Friday, June 5, 2009

Page 43: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Binding Annotationsuniquely identify a binding

32

“jesse”@Username String

Friday, June 5, 2009

Page 44: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Binding Annotationsuniquely identify a binding

32

protected void configure() {

bind(String.class).annotatedWith(Username.class) .toInstance("jesse");

}

“jesse”@Username String

@Inject

public SmsTweeter(@Username String username) {

this.username = username;

}

Friday, June 5, 2009

Page 45: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Defining your own binding annotations

33

@BindingAnnotation

@Retention(RUNTIME)

@Target({FIELD, PARAMETER, METHOD})

public @interface Username {}

> This boilerplate defines a binding annotation> Everything is compile-time checked• IDE autocomplete, import, find usages• Avoids clumsy string matching

Friday, June 5, 2009

Page 46: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Instance Bindingsalways use the same value

34

8080@Port Integer

Friday, June 5, 2009

Page 47: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Instance Bindingsalways use the same value

34

protected void configure() {

bind(Integer.class).annotatedWith(Port.class) .toInstance(8080);

}

8080@Port Integer

> Best suited for value objects such as a database name, or webserver port

Friday, June 5, 2009

Page 48: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Using Scopes

photo courtesy of http://flickr.com/photos/houseofsims/3139640931Friday, June 5, 2009

Page 49: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Scopesmanage how many

> Scopes manage how instances are reused• because theyʼre stateful• or expensive to construct or lookup• or expensive to maintain

36

Friday, June 5, 2009

Page 50: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Scopesmanage how many

> Scopes manage how instances are reused• because theyʼre stateful• or expensive to construct or lookup• or expensive to maintain

36

Friday, June 5, 2009

Page 51: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Common scopes

> Unscoped: one per use• create it, use it, and toss it!• often the best choice

> @Singleton: one per application• for heavyweight resources• and application state

> @RequestScoped: one per web or RPC request> @SessionScoped: one per HTTP session

37

Everything is unscoped by default in Guice.

Friday, June 5, 2009

Page 52: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Applying scopesthe best way is to annotate a class with its scope

38

public class TweetClient {

...

@Inject

public TweetClient(Shortener shortener, Tweeter tweeter) {

this.shortener = shortener;

this.tweeter = tweeter;

}

Friday, June 5, 2009

Page 53: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Applying scopesthe best way is to annotate a class with its scope

38

public class TweetClient {

...

@Inject

public TweetClient(Shortener shortener, Tweeter tweeter) {

this.shortener = shortener;

this.tweeter = tweeter;

}

@Singleton

Friday, June 5, 2009

Page 54: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Applying scopesyou can specify scopes in a module

39

public class TweetModule extends AbstractModule {

protected void configure() {

bind(ConnectionPool.class) .to(ExecutorServicePool.class) .in(Singleton.class);

}

@Provides @Singleton Shortener provideShortener() {

return new TinyUrlShortener();

}

}

Friday, June 5, 2009

Page 55: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Defining Injections

photo courtesy of http://flickr.com/photos/gaetanlee/631004864Friday, June 5, 2009

Page 56: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Constructor injectionto supply dependencies when creating an object

41

public class TweetClient {

private final Shortener shortener;

private final Tweeter tweeter;

@Inject

public TweetClient(Shortener shortener, Tweeter tweeter) {

this.shortener = shortener;

this.tweeter = tweeter;

}

Friday, June 5, 2009

Page 57: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Constructor injectionto supply dependencies when creating an object

41

public class TweetClient {

private final Shortener shortener;

private final Tweeter tweeter;

@Inject

public TweetClient(Shortener shortener, Tweeter tweeter) {

this.shortener = shortener;

this.tweeter = tweeter;

}

Immutable

Friday, June 5, 2009

Page 58: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Method injectionsets dependencies into a new or existing instance

42

public class TweetClient {

private Shortener shortener;

private Tweeter tweeter;

@Inject void setShortener(Shortener shortener) {

this.shortener = shortener;

}

@Inject void setTweeter(Tweeter tweeter) {

this.tweeter = tweeter;

}

> Plays nice with inheritance

Friday, June 5, 2009

Page 59: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Field injectionsets dependencies into a new or existing instance

43

public class TweetClient {

@Inject Shortener shortener;

@Inject Tweeter tweeter;

public TweetClient() {}

> Concise, but difficult to test

Friday, June 5, 2009

Page 60: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Injecting Providers

photo courtesy of http://flickr.com/photos/toasty/535851893Friday, June 5, 2009

Page 61: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

The Provider interface

45

public interface Provider<T> {

T get();

}

Friday, June 5, 2009

Page 62: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Injecting a Provider

46

public class TweetClient {

@Inject Provider<Shortener> shortenerProvider;

@Inject Tweeter tweeter;

public void postButtonClicked() {

String text = textField.getText();

if (text.length() > 140) {

Shortener shortener = shortenerProvider.get();

text = shortener.shorten(text);

}

...

}

Friday, June 5, 2009

Page 63: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Why inject Providers?

> to load lazily

> to get multiple instances• for example, if you need multiple

DatabaseConnections

> to mix scopes• for example, to access request-scoped objects from

a singleton-scoped object47

Friday, June 5, 2009

Page 64: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Leveraging Guice

> Modularity> Type Literals> AJAX via GWT> Servlets> AOP> Introspection SPI

48photo courtesy of http://flickr.com/photos/niff/87501285

Friday, June 5, 2009

Page 65: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

ModularitySeparate implementation from interface

49

Friday, June 5, 2009

Page 66: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

ModularitySeparate implementation from interface

49

API

API

APIAPI

API

Friday, June 5, 2009

Page 67: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

ModularitySeparate implementation from interface

49

API

API

APIAPI

API

API

API

APIAPI

API

Friday, June 5, 2009

Page 68: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

ModularitySeparate implementation from interface

49

API

API

APIAPI

API

API

API

APIAPI

API

API

API

API

API

Friday, June 5, 2009

Page 69: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Type Literals

> Like the language itʼs built on, Guice loves types• Set<User> is distinct from Set<Tweet>

50

@Injectpublic SocialView( Set<User> followers, Set<Tweet> tweets) {

...

}

public void configure() {

bind(new TypeLiteral<Set<User>>() {}) .toProvider(FollowersProvider.class);

}

Friday, June 5, 2009

Page 70: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

AJAXTodayʼs web apps are complex

51

> Testable• across browsers• without browsers

> Modular• reuse code across applications• and across platforms

Friday, June 5, 2009

Page 71: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

AJAXTodayʼs web apps are complex

51

> Testable• across browsers• without browsers

> Modular• reuse code across applications• and across platforms

Friday, June 5, 2009

Page 72: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

AJAX via GWTand GIN > Zero runtime cost: GIN generates

JavaScript from modules> API compatibility with Guice

• Great for GWT-RPC• Test without a browser

52

public class MyWidgetClientModule extends AbstractGinModule {

protected void configure() {

bind(MyWidgetMainPanel.class).in(Singleton.class);

bind(MyRemoteService.class) .toProvider(MyRemoteServiceProvider.class);

}

}

Friday, June 5, 2009

Page 73: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Servlets

> Configure your servlets programatically> Use @RequestScoped and @SessionScoped to

manage application state safely and easily

53

Friday, June 5, 2009

Page 74: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Servlets

> Configure your servlets programatically> Use @RequestScoped and @SessionScoped to

manage application state safely and easily

53

public class TweetSearchServletModule extends ServletModule {

protected void configureServlets() {

serve("/search").with(TweetSearchServlet.class);

}

}

Friday, June 5, 2009

Page 75: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

AOPaspect oriented programming

> You can apply method interceptors to injected objects• This is fantastic for cross-cutting concerns like

transactions, security, and performance

54

Friday, June 5, 2009

Page 76: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

AOPaspect oriented programming

> You can apply method interceptors to injected objects• This is fantastic for cross-cutting concerns like

transactions, security, and performance

54

public class DatabaseTweetStorage implements TweetStorage {

@Transactional

public void saveTweet(String message) {

...

}

}

http://www.wideplay.comFriday, June 5, 2009

Page 77: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Introspection SPIservice provider interface

55

> Module and injector internals are available via a mirror SPI• Inspect, analyze and rewrite bindings

Friday, June 5, 2009

Page 78: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Introspection SPIservice provider interface

56

Bindings

• ConstructorBinding

• ConvertedConstantBinding

• InstanceBinding

• LinkedKeyBinding

• ProviderInstanceBinding

• ProviderKeyBinding

• ProviderBinding

• UntargettedBinding

• ExposedBinding

Elements

• Binding

• InjectionRequest

• StaticInjectionRequest

• MembersInjectorLookup

• ProviderLookup

• Message

• PrivateElements

• TypeConverterBinding

• TypeListenerBinding

• ScopeBinding

• InterceptorBinding

Model

• InjectionPoint

• Dependency

• HasDependencies

• ProviderWithDependencies

• TypeConverter

• TypeEncounter

• TypeListener

• InjectionListener

Visitors

• ElementVisitor

• BindingScopingVisitor

• BindingTargetVisitor

Friday, June 5, 2009

Page 79: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Introspection SPIservice provider interface

57

> Guice uses it internally for...• createInjector()• module overrides• graphing

Friday, June 5, 2009

Page 80: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Introspection SPIservice provider interface

57

TweetClient

<init>

Tweeter Shortener

SmsTweeter

<init>

@Username

String

TweetModule.java:34

"jesse"

TweetModule.java:38

#provideShortener()

> Guice uses it internally for...• createInjector()• module overrides• graphing

Friday, June 5, 2009

Page 81: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Wrapping up...

> Dependency injection leads to testable and reusable code

> Guice makes dependency injection easy• plus it enables scopes• and it integrates neatly with the other APIs you use

> It works on both Java™ SE and Java™ EE• Plus Android, App Engine and GWT (via GIN)

58

Friday, June 5, 2009

Page 82: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

For more information...> Usage, extensions, and best practices

59

depinj40manning.com/prasanna

JavaOne09apress.com/

http://code.google.com/p/google-guice/

Friday, June 5, 2009

Page 83: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

More from Google at JavaOne...> Building Enterprise Java™ Technology-Based Web

Apps with Google Open-Source Technology• Session TS-4062, coming up at 16:10

60

Questions?

Friday, June 5, 2009

Page 84: Introduction to Google Guice: Programming is fun again!€¦ · Overview > Motivation • Ugh, factories arenʼt fun > Using Guice • @Inject is the new new > Leveraging Guice •

Jesse Wilsonhttp://code.google.com/p/google-guice/

Friday, June 5, 2009