views:

920

answers:

3

Google Guice provides some great dependency injection features.

I came across the @Nullable feature recently which allows you to mark constructor arguments as optional (permitting null) since Guice does not permit these by default:

e.g.

public Person(String firstName, String lastName, @Nullable Phone phone) {
    this.firstName = checkNotNull(firstName, "firstName");
    this.lastName = checkNotNull(lastName, "lastName");
    this.phone = phone;
}

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

What are the other useful features of Guice (particularly the less obvious ones) that people use?

+15  A: 

None of 'em are intended to be hidden, but these are my favorite 'bonus features' in Guice:

Jesse Wilson
+6  A: 

I like how totally open the Scope interface is: basically, it's just a transformation from Provider to Provider. (Okay, from Key and Provider to Provider)

Want some things to be basically Singleton, but re-read from the database every half hour? It's easy to make a scope for that. Want to run some requests in the background, and have a scope that means "all background requests started from the same HTTP request?" It's relatively easy to write that Scope too.

Want to scope some Key on your server during tests so that it uses a separate instance for each test that you're running from a client? (With the test passing the test id in a Cookie or extra HTTP parameter) That's harder to do, but it's perfectly possible and so someone's already written that for you.

Yes, excessive abuse of Scope will cause Jesse to start hunting around for the stakes and garlic cloves, but its amazing flexibility can be really useful.

Daniel Martin
True on both counts!
Jesse Wilson
+2  A: 

One great feature of Guice is how easy it makes implementing method interceptors in any Module, using:

public void bindInterceptor(
    Matcher<? super Class<?>> classMatcher,
    Matcher<? super Method> methodMatcher,
    MethodInterceptor... interceptors);

Now, any method matching methodMatcher within a class matching classMatcher in that Module's scope is intercepted by interceptors.

For example:

bindInterceptor(
    Matchers.any(),
    Matchers.annotatedWith(Retryable.class),
    new RetryableInterceptor());

Now, we can simply annotate any method with @Retryable and our RetryableInterceptor can retry it if it fails.

David Y. Ross