Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain what com.google.inject does?

I've seen a class declared with its only constructor being annotated with @Inject. And I don't see the one constructor being called anywhere in the entire project.

So two questions:

<1> What does @Inject mean? (What does it do? Why is the constructor being annotated with it?)

<2> As mentioned, the constructor never gets called directly, does that have anything to do with the fact that it is annotated with @Inject?

like image 717
One Two Three Avatar asked Mar 20 '13 22:03

One Two Three


1 Answers

Google Guice is a dependency injection library that allows you to construct objects simply by declaring relationships between them. Objects are constructed as they are demanded to construct other objects. You can also implement abstract classes or interfaces with different implementations by configuring Guice, which makes it very useful for running or testing your code.

@Inject annotates constructors and methods that determine what an object needs to be initialized. There are also a lot of other annotations that determine how Guice works. But simply annotating objects isn't enough; you also have to configure them with Guice bindings.

Here's a really simple example (from one of my applications). I have a MySQLDataTracker that requires a MysqlConnectionPoolDataSource:

public class MySQLDataTracker extends ExperimentDataTracker {
    @Inject
    public MySQLDataTracker(MysqlConnectionPoolDataSource ds) {
        ....
    }
}

Note that MySQLDataTracker extends ExperimentDataTracker, an abstract class that can be implemented several ways. In my Guice bindings I declare that

bind(ExperimentDataTracker.class).to(MySQLDataTracker.class);

This declares that whenever I want an ExperimentDataTracker, a MySQLDataTracker will be constructed. I also need to make sure that the requisite object for constructing this is available, so I declare a provider:

@Provides @Singleton 
MysqlConnectionPoolDataSource getMysqlCPDS() {
    return (some thingy I construct...);            
}

This says that there should only be a single connection pool data source. It also means that when I try to get an instance of ExperimentDataTracker, Guice has everything it needs to construct it. If I didn't have the above, it would throw an error.

ExperimentDataTracker tracker = injector.getInstance(ExperimentDataTracker.class);

However, it doesn't stop here. Other things depend on the ExperimentDataTracker, so it's used in turn to inject other objects. At the top level of my code there is actually only one call to getInstance, which makes Guice construct pretty much everything. I don't have to write the new statement anywhere.

I'm a big fan of Guice after seeing how it reduced the need for me to initialize a bunch of objects in order to initialize other objects. Basically I just ask for the object I want, and poof! it appears.

like image 92
Andrew Mao Avatar answered Sep 27 '22 22:09

Andrew Mao