Google I/O 2009 – Big Modular Java with Guice

Google I/O 2009 – Big Modular Java with Guice


Lee: All right, thanks,
everyone, for coming. Um, first off,
my name’s Bob Lee. And I’ll be introducing you
to your speakers today. Before we get started,
I just want to remind you at the end of the session if you’d share your thoughts
and give us some feedback, we’d really appreciate it. Um, so I created Guice
about three years ago. And we open sourced it
two years ago. And it went on to win
the Jolt Award. And just last week,
we introduced Guice 2. And nowadays at Google, pretty much just about every
Java application also happens to be
a Guice application. And there are–
we found that they’re a lot smaller and a lot more
maintainable for it. So our first speaker
is Dhanji. And Dhanji has been
working on Guice since before he even
came to Google. And he’s responsible
for kind of our more Enterprise layer. You know, it integrates
Guice with servlets and whatnot. And Dhanji’s also
written a book on dependency injection, which is heavily
focused on Guice, and I sure hope
he’ll plug it in the talk. And Dhanji also works
on Google Wave, which you guys
learned about this morning, and, uh… which also happens to be
a Guice user. Next, we have Jesse Wilson. Uh, Jesse Wilson’s
kind of the Guice star. He is responsible for–
“player.” [laughing] He’s responsible
for most of the development on Guice 2,
and he did an incredible job. Thanks.
Jesse: Cool. All right, uh… you’ve already got our names. Um, so I guess we should
get started. Uh, so we’ll start out
by just saying what are you
expecting to get by sitting with us
for the next hour? Um, Guice is all about
dependency injection, and that is
the Hollywood principle. You know, don’t call us,
we’ll call you. So if you take
that principle and apply it to your
Java classes, Guice is sort of
what comes out of it. It’s dependency injection
invented by Martin Fowler, and we’ll just talk about
how Guice works and what you will– by applying Guice
to your application, you’ll get more reusable code,
more modular code, more testable code, and you’ll actually write
less code to do this. So… uh, do you want to do… Dhanji: Okay, so our talk
is split up into three parts. The Motivation,
Using Guice, and Leveraging Guice. So most of it’s gonna
be introductory. We’re gonna talk about
why we think you need
dependency injection or what the drawbacks are of not using
dependency injection. Uh, most applications,
sadly, even today don’t make use of dependency
injection, and by that, I mean
the design pattern, not necessarily Guice or any of the other frameworks
that are out there. So it’s important
to understand where we’re coming from
when we say Guice makes your lives
easier by first looking
at how your lives are currently difficult. [Jesse laughs] Uh, so, and then we’re
gonna talk about the API itself, what @Inject means. How @Inject replaces
your factory code. And, uh, and then finally
we’ll take a look at the ecosystem and we’ll spend some time
looking at all the extensions
that people have built around Guice that make
your lives really easy. Jesse: Okay, so we’re gonna
write a Twitter client. Um, Twitter is taking
the world by storm, including Google. And so just to demo
the code that you might write, we’ll use Twitter
as our example. We’ll start by writing
some code using the factory pattern, and we’ll show
all the drawbacks. And then we’ll move to Guice
and show what happens and how your code changes. So hopefully, the code
that you’re looking at will be familiar,
and you can see, you know, “Oh, that’s code I would have
written,” or something. And then we’ll show
how your code would change if you were to use
dependency injection, and then if you were to use
dependency injection and Guice. So here’s some code
you might write. This is the ClickHandler
for a– the post button on
a Twitter client. And so the idea is
is that when somebody clicks “post,” we pull the text
out of the text field, see if it’s too long. If it’s too long,
we try to shorten it using TinyURL shortener. And then we tweet it off, and we’re using SMS
as our transport to send our tweet
to Twitter servers. So you may have noticed
that the code in this example actually builds
its dependencies immediately. So we say
new TinyUrl.Shortener and new SmsTweeter. And this is–
this is really convenient and it’s really terse but there’s a lot
of problems with it. Most notably, this code
doesn’t lend itself to testing. Um, we can’t run this code
and say, “I’m gonna write a test to make sure
everything’s working,” because every time
you run that test you’re actually gonna end up
doing an SMS. So that means that you have
to have a device that has an SMS
to run the code on, and you have to pay the SMS
bill at the end of the month if you do that. And also, you’re also
sort of at the mercy of whether or not
Tiny URL is working today. Dhanji: And it
doesn’t really help with testing automation. Jesse: Yeah. So tell us
what factories are, Dhanji. Dhanji: Okay,
so the traditional solution to that problem
has been factories. So a factory
is a third-party object it’s just–it’s another
class that we’ve written– that separates
the post button clicked method and the class
that it contains from the actual services
that it requires. So here, we don’t have
a direct dependency. We have
an indirect dependency. So the shortener is now
not necessarily a tiny URL shortener. It’s just something we get
from the shortener factory. And similarly,
for the tweeter factory. All right? Now, the factory itself is directly dependent
on the SMS tweeter, for instance. Uh, so in this case,
what we’ve done is we’ve taken
that hard dependency that we had between
the post button handler and the actual services
that we want, and we’ve inserted
one layer of abstraction in between. It helps us, but not quite. Let’s see why not. Jesse: So immediately,
one problem is you have to actually write
this factory class. And so, if you have
a whole bunch of classes, that means you have to write
a whole bunch of factories. And this is code
that slows you down. It’s not very interesting. Uh, it’s another thing that
you have to version control and code review,
and it’s just more code that doesn’t actually
get you anywhere in writing tweet–
Twitter clients. So, uh,
as Dhanji alluded to, the factory adds
an interaction layer between the Tweet client
and the SMS twit–tweeter that is actually going to be
doing the implementation for us. But, unfortunately,
the dependency is still there, indirectly. And so what happens is
when we write applications in this style, anything that you depend on you need to compile
at the same time. So you’ve got this
compilation time dependency, and what ends up happening is you have to build
your entire application any time you want to build
any part of your application. Your application
isn’t very modular. And so if we take this
to the logical extreme, what happens
is your application blows up in a firestorm of pain
and dependencies because now everything
depends on everything. So the other problem
with the factory is it’s awkward to test. So I was writing a test
for our tweeter client, and I wrote this. And so I set up,
uh, a mock tweeter, which lets me intercept
the text that gets tweeted. Instead of sending it to SMS, I can actually just take
an in-memory object and get the tweet from there. So I wrote this test. Dhanji: Well, that’s a good
start that you have there. So you’re using
a special mock tweeter in your factory. So now, when you call “get,” it’s gonna get
the mock instance. But I’m not quite
satisfied with this. Can you tell me
what’s wrong? Jesse: So the problem is that when I’m using
this mock tweeter, my test is gonna run, we’re gonna click
the post button, we’re gonna get the text
out of the tweet– out of the mock tweeter
at the very end on this last line. But the problem is
is that, now, I’ve left
my mock tweeter behind. I forgot to clean up
after myself. Fortunately,
there’s an easy fix, and that is that you have
to actually add code to tear down the mock tweeter
at the end. So whenever you write
this factory pattern, you don’t even need to worry about just setting up
your mocks and getting your tests–
your application testable, you have to also worry about tearing everything down
afterwards. Dhanji: This is a lot better,
but it’s still not perfect. Jesse: Oh, okay. So…it turns out that this still
isn’t sufficient to test with factories because you still
need to worry about the case where,
if my test fails, it’ll throw in
the assert method and it won’t actually
get to tear down my fac– tear down my mock tweeter. So you actually need
to put it try finally clause. This is really ugly code. You don’t want to see it
in your application. It adds another layer
of control flow that you don’t really
have to think about. And we haven’t even gotten
to the point of setting up
the TinyURL mock yet, so… Dhanji: So you guys see
it’s not just your factories that get polluted with
all this extra code in order to enable testing. But even your tests
are polluted with all this extra code
in order to enable testing. Jesse: Yeah, yeah. Uh…the problem is
is that when testing becomes
this complicated, you just don’t want
to write any tests. And if you don’t write tests, you don’t have confidence
in your application, and you don’t
get to ship Wave on time. So, uh, Dependency Injection
by hand. And Dependency Injection
is sort of a technology
or design pattern that addresses this problem
very delicately. So the principle is
instead of saying, “Hey, shortener factory,
give me a shortener; hey, tweeter factory,
give me a tweeter,” we pass those in. So here’s the constructive
for TweetClient. And it actually takes
a shortener and a tweeter. And now it’s the caller’s
responsibility to decide which implementations
to use. This is this Hollywood
principle again. We’ll call you
with your dependencies. Don’t ask for them.
They’ll just be passed in. And what’s absolutely
brilliant about this is that now we don’t need
to worry about passing in real dependencies
in our, uh, we don’t
have to worry about setting up teardown
in our test. And since we’re passing them
into the constructer of TweetClient here– so I say new TweetClient, and I pass in the dependencies
I want to use– not only do I have to not
worry about tearing it down, but I also don’t have to worry
about forgetting something. So you may have written
applications where, you know, you get your test,
you get everything compiled, and you run your test, and then at runtime
it fails immediately because you forgot
to prepare some factory. You know, you forgot
to initialize something or get something started up. And so now your application
gets this sort of gross, bootstrap system where in order to actually
write a test, you need to, you know,
start the service, connect to the database,
do this, the other thing, test that the SMS radio
is turned on, and now we can test. Well,
with dependency injection, your dependencies
are obvious and they’re part
of your API. But this is where dependency
injection breaks down. Okay, so what we have here
is a client factory, and it does all of the work
of providing the dependencies
to our object. But we’ve just moved it
one step further. We had the tweeter factory and we had
the shortener factory. Uh, but now we’ve, like,
pushed it one step further in order to make
our tweet client dependency injectable. So, I mean,
we’ve saved a little, but we’ve still got our
factory code to write and maintain, and it still looks ugly, and there’s still
the same problem. It’s just one step removed. So the idea of all
this dependency injection is we’ve broken
this hard dependency from tweet client onto
its TinyURL shortener and SMS tweeter, and by moving it, we only
depend on the interfaces, which is just fantastic. It means we can compile and test
and do all these things. But we’ve really just
shifted the dependency over to our tweet clients
in our factories, and we just had to write
a lot of factories to get this done, right? There’s–there’s
three factors here. That’s a lot of code
that you have to write. And so we have to have
something else. There’s got to be
something better. And that something is Guice. So with Guice,
you take your factories and you replace them with a combination
of injectors and modules. And so instead of writing
all about imperative code
to figure out how to build an SMS tweeter,
and, uh, an URL shortener, instead, you create a module, and this maps
the implementations, the interfaces
to their implementations. And injector
is a Guice-applied class that basically acts
as your factory, and it’s one-stop-does-
everything factory for your application, and it does it in
a dependency injection idiom. Dhanji:
And, more importantly, it’s a factory
that you don’t have to write and you never
have to maintain. Jesse: Yeah, yeah. All right, so now can
configure our dependencies using a module. And so, instead of writing
that 12 lines of factory for tweeter and 12 lines
of factory for shortener and 12 lines of factory
for everything else, instead,
we have one statement which is bind interface
to implementation. And this is how
you configure Guice, and that creates an injector
that works the way you’d like. So the change
to the client code is you add
the inject annotation, and that just is a signal
to Guice to say whenever somebody
wants to factory construct a tweet client, call this constructor,
so… Dhanji: So it’s–we’ve
taken that entire factory with all
of that boilerplate code and that testing code
that accompanied it, and shortened it to the one
little @Inject annotation that you see there. And that’s all Guice needs in order to be able
to provide this class with its dependencies. Now, that’s a great saving. Jesse: [whispering]
Yeah, yeah! Especially since
it’s such a savings encode, you’ll actually
tend to do it. And we believe that when
you use dependency injection, you’ll write better codes. You’ll write better code,
more testable code, more modular code. Um, here are the four lines
of code that you need to bootstrap Guice. Uh, you need to create
an injector with your module
or your list of modules. Then you can
use that injector to get an instance
of something. So this is just like
your factory used to do. Now you can say, “Hey, injector,
give me a tweet client,” and it’s parameterized on
what you want it to construct. And it’s fully type-safe. So if you’ve ever used Spring dependency
injection tools, then you’ll notice that
it’s not type-safe, and you’ll to do
a lot of casting and you need to do
a little finger crossing to make sure that what
you ask the injector for is what you get. With Guice,
it’s fully type-safe. The type that you pass in
is the type it will return. And if it’s not there,
it’ll blow up spectacularly and tell you all of the details
of what went wrong. So that’s
the motivation for Guice. And now we’re gonna just
dive into all of the minutiae
of the Guice API and explain how you use it, what the day-to-day life
of Guice development is like. So why? Dhanji: Okay, so we’ve already
said that boilerplate code is messy and it’s difficult
to test and maintain. And it’s just
nothing that, uh, we– as a developer, you want
to spend your time doing. But there are also
other reasons to use Guice. Like Jesse said,
there’s a lot of type safety that you gain from Guice. And this is because
when you tell Guice, when you give it
that bind statement, that’s actually
a signal to Guice to go out there
and look at that class and make sure that
all the dependencies for that class
are also available, and that’s valid in a way
in which it can construct it
at runtime for you. And that’s–
that’s really useful. More often than not,
you’ll find that fixing one small error
by hand in a factory and then recompiling– you go a bit further
down the line, you find another error, but Guice does
all of this type checking upfront for you and gives you
a long error list the first time
you deploy it. Jesse: It gives you
JavaC-style errors that you can even click on and navigate
right in your code to the bind statement
that didn’t work. Um, in addition,
when you use Guice– this is really
the real value of Guice, and this is growing
as our community matures. You get scopes, which is
an absolutely humungous, cool feature. You get aspect-oriented
programming, which is something
that you may like. It turns out to be
very, very convenient in your larger, Enterprisey-style
applications, as well as any application
where you have cross-cutting concerns. And there’s
tight integration with a whole bunch
of different APIs that you already
are using, such as servlets
and databases and RPC systems, et cetera. Oh! And, uh– Dhanji: Google Wave. Jesse: If all these technical
reasons weren’t enough, well, Wave uses Guice, so why aren’t you, right? All right,
so in a nutshell, classes have dependencies. And modules define how these dependencies
are resolved. This is the–this
is the whole concept, right? You have code,
it has dependencies. Today, you use factories, And with Guice,
it’s the same thing. You have dependencies. And then you configure it
with Guice. You configure
your dependencies and the resolution
using modules. So let’s investigate
that, uh, module resolution. And that’s called a binding. Dhanji: Okay, so– Jesse: I’ll go.
Dhanji: You want to do it? Jesse: All right,
so we’ve got a module with four bindings here. Uh, there are the three
statements in the code, the bind tweak line–
the bind tweeter, bind string,
those lines. And then method that has
@Provides annotation. And so these
are four bindings and we’ll go into detail and explain how
each of them works. All right, so… Dhanji: [laughs] Okay, so this
is a simple bind statement. All this says
is it tells Guice to look in that class
and use it any time it appears as a dependency
in any other code that you have. So what you need to do
in the tweet client is place an @Inject
annotation, like we saw just earlier, on the constructor
that you want to use, and all the dependencies
of that constructor will be filled in
for you by Guice. Jesse: So, uh… Whoops, this one. All right, so the next
type of binding is called a provider method, and this is really,
really handy, and its new
in Guice version 2, which we released last week. So a provider method is whenever somebody
asks me for this type, run this little bit of code in order to calculate it
or to compute it or to fetch it
or to construct it. So this sort of is your
traditional factory method type of operation where
you can create something, configure it,
and then return it. And the way you do
a provider method binding is somewhere
in your module class you have a method with
the @Provides annotation and the return type
that you’d like to bind. So in this case, we say, @Provides Shortener, which says this method
is a binding for Shortener, and then whenever Guice
needs to inject a shortener or to find
a shortener for somebody else’s
dependency, it will run this code. And what’s really handy
about provider methods is that they can have
dependencies of their own. So if you want to provide
a shortener and it has a dependency
on some HTP factory or something like that, you can pass
that dependency in via the parameter
of the method. So not only can
your classes have methods, but your providers–your
provider methods themselves can have dependencies, because your application
is effectively a big graph
of this depends on that. You know, my user interface depends on the components
inside of it. Et cetera. All right. Dhanji: Okay, so this
is a slightly longer form of the bind statement. And what we’re saying here
is bind this interface to this implementation. So tweeter is the interface
that we have. We don’t know how the tweets
actually go out. Um, but SmsTweeter
does now. SmsTweeter sends them
over the short message service. So all this is saying
is every place that you see tweeter
as a dependency, make sure that SmsTweeter
is provided. And the great saving here is,
of course, none of the client code knows that there
is an SmsTweeter being used underneath. It just uses it when
it’s available at runtime. Jesse: Yeah, so, you know,
six months down the road, if we decide that
the SmsTweeter isn’t optimal, or if we want to use
a JSONTweeter or some other protocol, all we have to do is change
this one statement and say, “Okay, now I’m gonna
bind my tweeter “to my JSONTweeter
of my AJAXTweeter or my XML,”
or something like that, any transport
that would be used. Uh, so what’s actually happening
behind the scenes here is there’s two bindings. There’s the binding
for tweeter to SmsTweeter. And then there’s
a second binding, which is SmsTweeter
to its own constructor. So when Guice sees this, it’s actually going to create
a binding for tweeter, and then it’ll look
at the SmsTweeter’s binding. And in this case, it’ll just
use that class as constructor. All right. Uh, Binding Annotations. So, so far, we’ve always
been talking about the unit of a dependency
is a type. So you can say, “Okay,
I depend on a tweeter or a shortener.” But oftentimes, the type
doesn’t uniquely identify what you really want
in your dependency. So if you say, “Okay,
I want my database address,” or, “I want the port
I’m supposed to bind on,” it’s not really
sufficient to say, “Just inject a string,” because there may be
multiple strings and you need to really
identify, “Okay, I want the string
that is the database addressed, “or the string that is– the integer
that is the port number.” And so Guice uses
a type-safe way to identify bindings in addition
to the bindings type itself. And these are called
binding annotations. And so you can annotate
a parameter with an annotation
that you define that identifies which instance
of that type you want. So in this case,
I’m binding the string “jesse” annotated with Username. And this is, again, indirect. So we can say,
“Okay, I want a… uh, an annotation
called port number or an annotation called
database address.” So you can use Guice
to configure not only your class dependencies, but also, all of your
configuration dependencies. So you can–you don’t
have to worry about having these
separate mechanisms for how you connect
to your database, how you connect
to remote services, you can use Guice
to configure everything. And this is the standard
boilerplate you need to define user annotation. I’m not gonna go too much
into detail on it, but this is just–every time
you want to define a custom name
for something, use this boilerplate. You’re saying
about his and hers? Dhanji: Oh, yeah,
so the great thing about this is it does look like
a little bit of boilerplate, but the awesome saving
is it’s purely a bit of metadata, right? You can reuse it
across your application for several purposes. You might bind
“jesse” to the user name, where you use it
in a login-style scenario. But you might
bind something else to a user name somewhere else
for a different type. So it’s completely flexible, and it doesn’t force you
to bind directly to the actual implementation
that’s underneath. So in the tweeter case, you might bind it
to a current transporter, paid transport, and, really, that paid transport
is an SMS transport. But you can reuse
the paid annotation to bind, say, a credit card
transport– or a credit card
service, sorry– or any number of other
dependencies. Jesse: And one really
nice thing about the way Guice does dependency
injection is that this annotation is compiled
into your code. So this is just standard
Java code, and if you spell
user name wrong, the compiler will tell you,
or, more likely, if you’re using an IDE
like IntelliJ or Eclipse, it’ll highlight it in red, and make sure you spell
everything properly. All right, so the last
type of binding we’re gonna talk about
is an instance binding. And we already sort of saw this
with the “jesse” example, where you can give
an actual value that you want to bind to. So, in this case,
instead of hard coating 8080 as a public data constant
in 10,000 classes, you can configure it
once in your module, and then everywhere
that you need that constant, you just inject it. And this really
overcomes this problem where, you know, if you decide you want
to run your FTP server on Port 22
instead of 21, you have to go in and change
10,000 pieces of code where that’s wired. And the, uh,
the main problem is that when you do
that type of approach, you either have the 10,000
different definitions of that or you have some file
called “constants” that everything else
has to depend on. So this is a nice balance. All right,
you talk about scopes. Dhanji: Okay, so scopes
are very interesting. They’re really hard for me
to define in one, simple way. So I’ll use the simplest
explanation that I could think of. For me, scopes
are about duration, right? You can talk about scopes
as a context, for instance,
an HTP request is a scope in Guice. Or an HTTP session,
which is a series of requests that come in a sequence. Or you can talk
about singletons, objects that live throughout
the life of an application. That is a Scope
in itself. So these are short
or longer durations during which any dependency
injection that’s performed will always receive
the same instance of the dependency. Jesse: So, uh, when you
do your factory pattern, you’ll often have, you know,
a private static constant that is, you know,
the tweeter. And when you say,
“Give me the tweeter,” you might lazily
instantiate it. And then, for the rest
of your application, you always get
the same instance. With scopes, you can
get that sort of application-wide constant without having to actually
write the statics and without
having to compromise your application’s
testability. In our cute diagram here, we have this sort of long,
blue line, which is the duration
of the application. Um, this is a very abstract
example, without a legend, so I’ll describe
what I’m thinking when I’m drawing this. Um, the red bars
are HTTP sessions, and the blue bars
are HTTP requests. And so you can see
that the scopes nest inside of each other. So you can have, like,
your application lives for several hours
or several days or several months, depending on how
your uptime is. And then every session
gets its own context, and then every request gets its own context. And this
is the HTTP example, but you can come up
with scopes for any number
of different contexts that exist
in your application. Uh, so we’ve already
sort of talked about this. These are the common scopes. So the most natural one
is Unscoped, and that means that any time
you want a value, it will be created,
you use it, and then you throw it away. Uh, the opposite
is Singleton, where any time
you need a value it’s created exactly once, and you always, always
use the same one. This is great if your
application is stateful, and you want
to do something like track the number of hits
on your sever since it was started. Because you can just say,
“Use a singleton,” and every time
somebody does something, you call increment. Uh, RequestScope
is fantastic. And it says, “For the duration
of my HTTP request, remember this value.” This is particularly handy if you’re doing
a several-tier application where you want to say, “I don’t really want
to go back to the database “every single time
I want to remember who the current user is.” You can just put that
in a RequestScoped object and it remembers. And SessionScoped
is the same process for the HTTP session. So if you have, uh,
if you have any session data, like a cache, this works
very nicely for that. So that’s how you apply scopes
to your objects in Guice. Uh, you just annotate them
with the name of the Scope. We’re very annotation happy
in Guice. And this is both
functional, because it says, “Okay, there will only be
one tweet client for the duration
of the application.” But it’s also documentation. So when you’re seeing this
class tweet client, and you’re maintaining it, the singleton annotation
is a really good hint that you may have to think
about concurrency when you’re maintaining this. Because singletons
are naturally– uh, need to be multithreaded
in multithreaded applications. All right, um, if you want
to apply a scope in a binding instead, you can also do that. So here we’re saying, “Bind my ConnectionPool
to the ExecutorServicePool as a Singleton,” which is
.in(Singleton.class). Or in your provide method
you just annotate the method. And that’ll mean that Guice will only call that method
one time, and then it’ll just
remember the value. And any time anybody
wants a shortener, it just uses
that same instance. Dhanji: Uh…cool, okay. So there are different
kinds of injections that Guice supports, and constructor injection
is the most obvious one. This is the one that
we’ve been talking about. This is where you pass in
all your dependencies via constructor, and you place
an @Inject annotation on the constructor to tell Guice to use it. Now, the advantage
to constructor injection is–is really great, because you can declare
your dependencies as final, which makes them immutable. Now, this is great
for any concurrent class where you have
multiple threads accessing the code
in the same class. Then you have no danger
of state leaking between these threads, because there
is no state, right? You don’t change the values. It’s also great
for publication, which is–which means
that once the value is set, it’s seen by all threads, and you never have
any danger of a NullPointerException. You also have
method injection, which is traditionally
called setter injection. And this is almost exactly
like constructor injection, but it’s called after
the constructors have run. And what this is
is just a simple setter method, so you pass in your dependency
via a setter. And the method doesn’t
have to be called Set Shortener
or Set whatever. It can be called
anything you like, so long as it has
an @Inject annotation and it doesn’t only
have to take the one parameter. It can take as many
arguments as you like, just like a constructor. Jesse: All right,
and lastly. Dhanji: Lastly, we have
this horrible form of injection that we don’t
want you to use, but we’re gonna talk about
anyway. And this is field injection. The thing
about field injection is that it’s
really concise, right? It’s an @Inject annotation
directly on the member that you’re, uh,
that you depend on. You don’t need
to set anything. Guice will set it for you
by reflection. The problem with this, and the reason
we discourage it, is that it makes testing
very, very difficult. Now, you have
to expose your fields. In this case, we’ve
exposed them as PackageLocal in order to access them
from a test class in the same package. Now, not only
is that ugly, it’s, um, it’s also difficult
for other tests that don’t
sit in the same package to get access to it. So we discourage this,
but in a pinch or in tutorial code,
it looks nice and it works. Jesse: It’s very,
very concise. So a lot of the intro
in the talk was about removing
boilerplate. And if you get–
if that’s why you’re here, I invite you to use
field injection. Although you’re losing out
on a lot of other benefits of dependency injection. All right, uh, let’s talk
about injecting providers. So thus far, we’ve always
been talking about I have a dependency. You get a single instance
of that dependency and you use it. Um, the provider interface
permits something new. And the interface
is very, very simple. It’s parameterized on “T.” So you can have a provider
of string and then “get”
will return string, or you can have a provider
of shortener, and “get”
will return shortener. So the provider’s type, it’s a factory
for a given value. So when you inject a provider
into your code– and I’m using
field injection here, shame on me– um, you can see that we don’t have to actually
get our shortener until we need it. So if we have somebody
who’s very terse and doesn’t ever write
tweets that are shorter than– that are longer
than 140 characters, we can avoid the cost
of constructing our shortener until we actually need it. So in this case, we say,
you know, if text length
is greater than 140, then go ahead and ask
the shortener provider for a value. We’ll use it, and then
we’ll let it go out of scope. So there’s a bunch of reasons
why you would use providers. Um, first is to load lazily, which is what
we just saw. So we don’t actually
have to worry about constructing
the shortener until it’s actually needed. It’s also useful
if you want to get multiple instances
of a value. So if you need multiple
database connections, instead of injecting
a database connection in your constructor,
you can inject a provider of the database connection, and then you can call “get”
once for each thread that you want to use
to connect, or once for each, uh,
each query that you need to run. Finally, providers
let you mix scopes. And so this
is where you have, uh, a singleton object that’s sort of the overseer
of everything. But it kind of wants to know
who’s asking who the current user is or what
their session contains. And so you can inject
a provider of user or a provider of session, and then use that
to look inside. All right, so thus far, we’ve talked about a lot
of the mechanics of using Guice. Now it’s time to get into
the real exciting stuff, which is how do we really start
to take advantage of Guice, and how does this really
change our applications? We’ve removed the boilerplate. We’ve become testable. But now let’s really start to figure out
how you can build absolutely fantastic
applications with Guice. All right, so this
is a fairly abstract diagram of a fairly abstract, uh– This is–imagine that this
is Google AdWords, okay? [laughs] So these
are all of the classes in Google AdWords. And we are in sort of
dependency, uh, dependency
nightmare mode here, where we can’t compile
a single module without having
to build the whole world. Everything depends
on everything. And it’s really hard
to figure out, you know, how do I–how do I isolate
this one component so that I can reuse it
in AdSense or so that I can reuse it
in some other system? So you want
to avoid creating this really complex
spaghetti dependency, uh, application. So with Guice, the idea is that you are encouraged to divide
your application up into modules. So, in this case,
we have five modules, and they all communicate
with each other via the public API. And, uh, this is possible
with factories and it’s possible with
really good software engineering
discipline. But when you’re using
dependency injection, and Guice in particular, it becomes very easy to have
this type of discipline where you’re saying, “Okay, only
my API is exposed.” And the reason that this
is possible is because Guice lets you hide your
implementation details. So you only–
only your module knows about your
implementation classes. And then your interfaces
and your domain classes and all that can be
in your public API. All right, so did you see
that cool transition? All right, so here’s–
here’s where we’re at. We–we’ve written
this application, and we want to swap out
this entire component in the top right
with a new component, and when you use
dependency injection, it’s about
writing modular code. And modular code
really means that I can swap out
this blue one for a yellow one. And that can be a completely
different implementation written by a completely
different team. This is extremely powerful,
you know. You’re writing these really,
really big applications, things get slow,
things get complicated, and you know you want to say,
“Rewrite!” Well, Guice helps you
avoid the rewrite and all of the costs
with it because you don’t have
to rewrite the whole thing. You can just rewrite
this module, the particularly
painful one. Um, so that’s really handy,
but the other thing is is that not only can you take
an entire module, airlift it, and put in
a different implementation. You can also take that module
and reuse it in a completely
different application. So we can take our,
you know, our yellow module
from AdWords, and then go and use it
exactly the same in AdSense. And this
is extremely powerful. And this is the type
of reuse that was sort of
promised to us with object-oriented
programming, but hasn’t really
been within reach. You know, you write
the customer class in every,
single application because you don’t have
a customer module. And this sort of permits sort of your service-oriented
application where you can actually have
a module that says, you know, these are all
the APIs talking to my service. That’s… Dhanji: Okay,
so Wave is famously a GWT application. GWT is Google Web Toolkit. And, uh, for Wave, we don’t use this
in particular, but, um, GWT does support
Guice-like behavior using a library called GIN. GIN was written
by one of our Googlers and it provides
very similar functionality to Guice. When GWT is running
in Java mode, or hosted mode,
as they like to call it, it will defer to Guice to do all of the dependency
injection. And when it’s compiled
into JavaScript GIN will provide the intermediary
JavaScript Code to do
the dependency injection just like it would
work in Java. Now, it does everything without any runtime cost
whatsoever because the source code
that’s generated by GIN is exactly the same
source code you would write
in JavaScript to wire up all those objects
with one another. So that’s fantastic. The other great thing
is it’s the same API you use for Guice. So if you have a module
that you use in a server environment, and you’d like to port it
to the GWT environment, something that would have
been unheard of before GWT
and before Guice, you can do this today. It is a reality. Things like GWT-RPC, where you share code between the client
and the server really becomes possible now that you have GIN
sitting in this dual use mode. Okay, so the other
cool thing about Guice is– and particularly,
Guice 2, is the Guice
servlet extension. Now, the Guice
servlet extension is available in trunk. You can check it out, and there’s a separate jar
that you need to download it and use it. Jesse: It’s a separate jar,
but it comes with Guice. Dhanji: Comes with Guice.
Jesse: Yep. Dhanji: And it gives you
the request and session HTTP scopes
that we saw just earlier, just as an annotation, just like @Singleton was. that you get out of
the box of Guice. Now, these are really cool, but the servlet module
has a lot, lot more to it. As you see here,
you extend servlet module rather than abstract module when you’re creating
your Guice module. And what this gives you
is the whole extension to the binding language to configure servlets
and filters. Now, if you guys have ever
used web.xml in a HTTP sever,
like Tomcat or JEDI, you find yourself writing
a lot of declarative XML rules to tell you
how to route requests based on their URLs. Now, you can do all of that
with idiomatic Java. Just like you’re used to
with, you know, with bindings and how JEDI
would work under the covers without all this XML
in the middle. Now, that’s great because
we’re Java programmers, and we like to write Java. But it’s also great
because it’s type-safe. I can’t serve
a particular URL with something
that’s not a servlet. So you have all these
minor little enforcements that come into play
that add– give you this extra
level of confidence, yeah. Now, the other great thing
about the servlet module is that it has
a lot more extensions than just this. It allows you
to match URIs based on
regular expressions. It allows you
to bind keys so you can have
multiple servlets that are matched
in a dispatch order. All the power of web.xml
and a lot, lot more, and none of the pain. Jesse: Yeah, the part
that Dhanji was talking about– me about earlier is that when you move
your servlet configuration out of the XML file
and into modules, you get a modular design
for your servlets. And so what
that lets you do is you can actually create
a prepackaged module for some aspect
of your application, like authentication
or your admin servlet, and you can say, okay,
we’ve written the, you know, the single sign-on
servlet package, and we use that module in a whole bunch
of different applications, and you don’t
have to worry about configuring web.xml
for each. So if you’re
the single sign-on team or the security team and you have your own
servlet filters and your own servlets, you can give this to your
entire development staff at your company and say, “Okay, use this module
in your servlet application, “and you’ll automatically
get our filters “and our servlets applied, and there’s no other
integration work.” Whereas the alternative is is you have
to actually go in and edit
the web.xml for each. And that means that you’re
sort of discouraged from changing
your filters over time as your business needs
change. Dhanji: The other great thing
is we do this in Google Wave,
by the way. So we use
this modular design, so we have particular servers
that sit on the front end, and the single sign-on
is the same code that’s used all over Google, and we bring that into
Google Wave this way. And–and this morning’s demo, when you saw Lars doing
all those fancy, cool things with the collaborative
editing stuff, every single character
that he typed went through a Guice servlet
dispatch rule. Yeah, so is it fast? Jesse: [laughs]
It’s way fast. Okay, all right,
so one of the features I hinted at earlier is
aspect-oriented programming. And this is a very,
very powerful, very, very complex domain. And Guice gives you
sort of the sweet spot of what you want, which is method
interceptors. Um, so suppose you’re
writing a database thing, and you–you’re writing
this boilerplate where you need to set up
and tear down a transaction for every method called. So, traditionally,
what you’ll do is you’ll say
database connection.open, try, then do
your actual work. And then you’ll have,
you know, a catch clause and a finally clause and some teardowns
and rollbacks to handle the cases
where your business logic either failed or there was
an optimistic problem with your, um, your commit. So with aspect-oriented
programming, instead of doing all that stuff
all over the place, you separate
the cross-cutting concerns into interceptors, and they run
around your method. So in this case,
we’ve annotated database tweet storage
with @Transactional. And what this will do
is it’ll make sure that before and after
saveTweet is called, we set up a transaction
and then we make sure to commit or roll back, depending on how that,
uh, method completed. Jesse: Uh, do you want
to talk more about this? Dhanji: Well, this
is another extension to Guice that’s not available
in the Guice code project, but you can find it
in our documentation. It’s a very,
very convenient thing for people who use Hibernate
or Java Persistence API, which is the foundation
of Google App Engine’s persistence framework. So this is a bit
of boilerplate code, very much like the factories, but something that sits
in every method that does any work
with the database session. And it can all be
abstracted away with this one,
single annotation. And Guice enables us
to do this, yeah. Jesse: The other thing is
is that this AOP, it really fits hand-in-glove
for transactions. And there’s a handful
of other cases where it also fits
very nicely. So on my former project
in billing, we used AOP and Guice
to do security. And so you’d have a method
that says, you know, “Make payment,” and you would have
an annotation on that method that said @Secure. And that would require that whoever
was calling that method had a prior login. And you can
annotate your methods and configure
all this stuff just exactly as you need it
to fit your application. So you can define
your own annotations, and you can define
how those annotations behave. Uh, it’s fully pluggable, and in its core, Guice knows
nothing about transactions, it knows nothing about
servlets, it knows nothing
about security. But it supports all these things
to be added on with its own modular
architecture. All right, so the last part is that Guice
is fairly open to extension
and manipulation. So we’ve talked about
binding so far, and we’ve talked
about injections. All of this information,
all this metadata about your application
is exposed through Guice’s Introspection
Service Provider interface. And so, when you
define your module and you set everything up, Guice will actually give you
all of the metadata that is has internally so that you can take that
and analyze your application. Uh, the most interesting
one so far has been that we’ve been
graphing our applications. You find
really interesting things when you can take your entire
10,000 class application and spit it out
into a graph and say, “You know what? “That dependency there,
that one’s broken. We need to fix that.” And you can’t
do that type of thing by just
inspecting the code, reading line by line, because the modules are,
you know, modular. One’s over here,
one’s over here. The introspection API
lets you see it all at the same time. Uh, it’s also
used internally by Guice to do some of the more,
uh, testy, easy,
configuration-type things. So when Guice–when you
have a module and you know, you say, “Okay, I want 90%
of this module, “but instead of that binding
to the production database, I’d rather bind to
the QA environment database.” Or you know, the, uh,
the canary database. So you can take that module, override it with just
the stuff that you want, and you can
create a new module. And this all uses
the introspection SPI. It’s sort of built on top
of Guice’s own, uh… APIs. All right, so wrapping up. Dependency injection leads
to testable, reusable, modular,
maintainable code. And we love
dependency injection, but you really
want a framework. And Guice makes
dependency injection easy. It’s a, you know,
it’s very concise. You add that annotation. Very little boilerplate
that you have write. And once you’ve got Guice
independency injection in play, then there’s a whole new
avenue of components and modules that you can
use as well. So this is, you know,
your scopes, your AOP, your warp-persist,
your app engine integration, your Google App Toolkit
integration. And Guice is also
really lightweight. So we’re serious about this, and we don’t think
that it makes sense to include a sort of
large kernel in applications. So although Guice drives,
you know, some of the bigger
applications at Google, it also works
on Android. It’s a fairly lightweight,
simple library. And then it’s a got a sort
of pluggable thing so you can put the servlets
for App Engine or the UI stuff for Android, and it all just
sort of works seamlessly. All right,
and the book plug. Dhanji: Yep, so I’ve got
a book coming out calledDependency Injection.It’s mostly
a design patterns book, but it has a lot
of focus on Guice and another
framer of Spring, and if you use
that discount code and go to that URL, I believe you get
a 40% discount for one week. Jesse: Yep, Google I/O only. So, uh, you can get the book in Manning Early Access
right away. Dhanji: Yep, and then once
it’s ready, it’ll be
shipped out to you. Jesse: Yeah, the book
really goes into full detail about all of the stuff
that we’ve just breezed through in the last hour. And I guess now
we should open the poll up for questions. Um, we’re using
Google moderator. So if you guys
have your laptops handy and the Wi-Fi
is working well, you can
post questions there. Otherwise, please use
the microphones here. Um, thank you. All right. Question. man: How do I
compose modules? Jesse: How do you
compose modules? man: Take several small modules
and build a big one. Jesse: Yeah, so, um, the, uh, the–
the module API actually has a method where one module can
install another module. So you can say, “Okay, here’s my entire
front end module.” And then you may
have multiple teams, you know. You’ve got
your team in New York working on
the billing system, and your team in L.A. working on the user
authentication system, and a team in Mountain View
working on the features. Your front end module can
just install each of those. And what’s really nice
about that approach is that those modules are independently reusable. So those teams can work
independently of one another as well as, you know,
when you actually need to go out in production and you need
the whole team’s code all in one binary. You just compose it all
into one system. Um, now, if you have
multiple bindings for the same type– So if Dhanji binds his tweeter
to SmsTweeter, and I bind it
to JSONTweeter, Guice will detect that
at start-up time, when you call that
guice.createinjector method, and it’ll say, you know, these are the old
falling bindings that we had problems with. And, you know, this one
happened on line 45 of SMS module, and this one happened
on line 32 of JSON module. And it’ll help you
to resolve that. Dhanji: There’s also
a really simple way to compose modules. And that is when you’re
bootstrapping Guice, you just give it a list
of modules, and it’s just a simple
Java tool list. Give it as many modules
you like, it’ll be installed
in order. Jesse: Yep. Uh, so we got a question
from a moderator that Jesse
in Mountain View wrote. Uh, what apps
use Google Guice? So the ones at Google
that use it are, uh, you know, we started out
with Adwords. We had this really big
application fairly hard to maintain. You know, we had a lot of,
um, factories and a lot of static state and a lot of, you know,
database connections that were required for tests that had nothing to do
with the database. And so Guice really
rescued Adwords front end and gave it a couple more
years of life by making it so that,
all of a sudden, you could use certain components
of Adwords independently, and that’s breathed
new life into it. Um, there’s also Gmail, um, Orkut, Docs,
YouTube, Wave, um…
the… Dhanji: Pretty much every
new Google application these days. Jesse: All right,
“Is Guice Servlet module now a superset
of warp-core?” So, uh… Good question. [both laugh] Uh, so… Dhanji: The answer
to that is no. It’s–it has very similar
functionality. But warp-core
is now defunct. So Guice Servlet
takes precedence. It supersedes it. Jesse: Yep,
warp is still useful

34 thoughts to “Google I/O 2009 – Big Modular Java with Guice”

  1. I love Guice but don't quite like the infomercial style of making every other way look so ugly at the beginning of the video.

  2. Nope, he couldnt use else in this method, because text local variable can be changed in the first if block of code (see: text = shortener.shorten(text);).

  3. guice-servlet module, seems to be like going back. we moved the configuration from servlet code to XML in early 2000 and now we are going back..

  4. It would still have been a direct dependency, every class that goes into an if block has to be imported (i.e. loaded and initiated).

  5. Hollywood principle "don't call us, we'll call you."

    Bollywood principle "call us, we won't call you. No balance dude!"

    Haha… No offense, just a joke!

  6. At around 7th minute Jesse says if you compile a module you have to compile everything that it depends on?!!! it's not true. Test for yourself if you don't believe me. Define a class and inside one of the methods call another class that you've defined compile it. Then see the time of creation of the class files. Then go back and change the dependent class and compile again. It will still work without needing to compile the other class again. IDEs also keep track of these dependencies

  7. Don't like that there is a dependency on Guice for the annotations (or is there?). Should default to use the constructor with the most parameters

  8. @7:38 But if you are using JUnit (and it looks like you are), you can (and probably should) perform setup and tear down in the setUp and tearDown methods.

  9. @4:15 Another way would be to have overridable (i.e. non-final) methods that return a Shortener (and another one that returns a Tweeter). That way, you can write a subclass that overrides those methods with their own implementations that return mocks, or whatever.

  10. Hey guys – what do you think the junit setup/teardown methods are for… Not saying DI isn't needed, but your unit test makes a poor argument…

  11. one question though, when you are configuring your depencies in a module, at the end of the line/tree, your leaf dependencies will always have to be classes with no argument constructors, correct? There is no way, that you can configure juice to just inject you a class depends on a Long, for example. You would have to wrap that long in some wrap long class with a no argument constructor, or something of the sort. So, for example, if the smsTwitter need a Locale as input, that would be the end.

  12. I think that the point there is that the setup and teardown are boilerplate, no matter if you do it manually or using the JUnit methods.

    Using Guice you are supposed to not even need to setup and teardown.

  13. What's so bad about guava? It's useful to me every day. Think of how many lines of code it would take e.g. to hand-roll Joiner.on(",").skipNotNull().join(emailAddresses) in terms of StringBuilders, or to write a decent concurrent multimap, or even just to read out all of a file into a byte array without first having to wire up a gazillion different IO classes.

  14. Why reinventing Spring? there is nothing I saw in this video that could convince me to use Guice instead of Spring. And I'm not even talking about other Spring Projects…

  15. I thought Juice was spelled with a J not G.
    GUICE. JUICE
    GONE. JUNGLE
    GET. JET
    GATHER. JUSTICE

    Maybe that's why my nickname is "JuiceMan" go figure, lol.

  16. what stops them from creating with new TwitterFactory("mockTestSmsProviderUrl") and not dealing with ugly static methods that won't work in multi-threading environment anyway and will make them always to write a tearDown method to cleanup parameters passed via static method? (i'm talking about https://www.youtube.com/watch?v=hBVJbzAagfs&t=8m20s example)

  17. Another good google guice tutorial at :

    https://www.youtube.com/playlist?list=PLp0ed20U4R4jknb4xYdhx3yJn5RhWECxn

Leave a Reply

Your email address will not be published. Required fields are marked *