Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Google Guice


Implicit Bindings

In the fortunes example, you've probably noticed that I never made an explicit binding for Chef. This is because bindings don't always have to be explicit. As a rule of thumb, if there is no ambiguity, Guice will figure it out for you. This applies to concrete classes. As shown in Listing 15, I could have configured an explicit binding to Chef. This is kind of redundant, so I usually don't bind concrete classes explicitly.

public class ExplicitChefModule extends AbstractModule {
  protected void configure() {
  // no to(...) because you can't bind to the same class
  bind(Chef.class);
  }
}
Listing 15: Explicit Binding for Chef

Next to these implicit bindings, provided by Guice, you can also reduce configuration yourself when working with interfaces. Guice comes with an @ImplementedBy annotation that lets you specify which concrete class implementation to use for an interface. For example, Listing 16 shows the same FortuneService interface from Listing 2, now changed to use @ImplementedBy.

@ImplementedBy(FortuneServiceImpl.class)
public interface FortuneService {
  String randomFortune();
}
Listing 16: Using @ImplementedBy

By using @ImplementedBy, you can get rid of modules altogether. Whether that's a good idea or not, I'll leave up to you to decide. I usually stick to modules, because they allow you to change your application's configuration in a single line of code, by including or excluding certain modules when creating the Injector. However, you can use @ImplementedBy to specify a default implementation, and then override it in a Module implementation. That way, when creating an Injector without any modules, you'll always get a default implementation.

Note: Module configuration always takes precedence over annotation configuration.

Scoping

Guice's default behavior is to create a new instance of an object each time that object gets requested or injected. Scopes allow you to customize an object's lifetime. The canonical example is the built-in singleton scope, which makes sure only one instance of an object exists for a given Injector and internal Key. This is much, much better than using singletons manually, because this does not involve using static factory methods (or writing any code at all). But, as with any singleton, you'll have to make sure that your class is thread safe if you're going to access it from multiple threads.

To apply a scope to our FortuneService bindings, we specify either a scope annotation or an instance of the Scope class. For a singleton, these are Singleton.class and Scopes.SINGLETON, respectively. In Listing 17, I mix both of these styles (not recommended).

public class ScopedModule extends AbstractModule {
  protected void configure() {
    bind(FortuneService.class)
     .to(FortuneServiceImpl.class)
     .in(Singleton.class);
    bind(FortuneService.class)
     .annotatedWith(Mega.class)
     .to(MegaFortuneService.class)
     .in(Scopes.SINGLETON);
   }
}
Listing 17: Using Two Styles to Apply a Scope

You can also apply a scope by directly tagging your class with the @Singleton annotation, but as with @ImplementedBy, bindings in modules always take precedence.

The question that now is, "Do singletons load lazily or eagerly?" The short answer is that this will depend on the Injector's Stage, as I mentioned earlier. If you want to make sure that your singleton is created at application start-up (loaded eagerly), regardless of the Injector's Stage or the binding's usage, you can specify that as in Listing 18.

Tip: Stage.PRODUCTION loads singletons eagerly; Stage.DEVELOPMENT does not.

public class EagerSingletonModule extends AbstractModule {
  protected void configure() {
    bind(FortuneService.class)
     .to(FortuneServiceImpl.class)
     .asEagerSingleton();
    bind(FortuneService.class)
     .annotatedWith(Mega.class)
     .to(MegaFortuneService.class)
     .asEagerSingleton();
  }
}
Listing 18: Eager Singleton Loading

Loading singletons eagerly might be useful to execute initialization logic for your application. You can even create dependencies between them in such a way that you're sure they'll come up in the right order. I've only talked about the singleton scope for now, because it's the only scope that ships with core Guice (guice-1.0.jar). The 1.0 distribution also comes with a guice-servlet-1.0.jar archive containing the web-specific (servlet-specific) scopes: request and session.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.