To show you all what this is I shall share with you some code I've used in one of my web applications.
I've created myself a service which I use for accessing data about a specific user. I call this the
UserService. For this I've created an interface.
public interface IUserService {
public UserModel createUser(final String firstName, final String lastName, final String emailAddress, final String password, final boolean administrator);
public UserModel getUser(final String emailAddress);
public void setUser(final UserModel userModel);
public List<UserModel> getUsers();
}
It's fairly straight forward and since I'm not trying to explain what interfaces look like or what they do we shall leave that out of this thread.
After this I create the actual UserService implementation against this interface and call it
UserService.
After this I create myself a new class called
GuiceModule. This class's purpose is to bind my interface
IUserService with the implementation we would like to create for it and in this case it will be the
UserService class.
public class GuiceModule extends AbstractModule {
@Override
protected void configure() {
bind(IUserService.class).to(UserService.class);
}
}
This class extends another class that comes with Guice for doing these injections called
AbstractModule, for API information on this module have a look at
AbstractModule (Guice 2.0 API)
As we can see here we override the method called
configure which will be what is called later on by the Guice API. In the configure method you can see that I use some methods that come with the Guice API and the AbstractModule called
bind and
to which binds my interface class to the actual implementation class. This means that whenever I add the @Inject annotation to another class and method and the method takes an IUserService it will create a new UserService instance for us.
To go from here and actually make this work we need to create the actual method we intend to use for doing the injection so in my application context when I start my web app up I create an
Injector and pass in a new instance of my GuiceModule to it. This way the injector will know that everytime we try to inject things we will look at the configure method of the GuiceModule to determine what gets injected.
final Injector injector = Guice.createInjector(new GuiceModule());
And here comes the fun part, I've created an abstract backing bean which I extend in all my page backing beans. I'm not going to go into what a page backing bean is and what its purpose is but in short its the bean that holds the members used on a page and the actions I wish to run on that page as well.
public abstract class AbstractBackingBean {
private SessionBean sessionBean;
@PostConstruct
public void handleInjections() {
final Injector injector = ApplicationContext.getInstance().getInjector();
if (injector != null) {
injector.injectMembers(this);
}
}
public void setSessionBean(SessionBean sessionBean) {
this.sessionBean = sessionBean;
}
public SessionBean getSessionBean() {
return sessionBean;
}
}
As you can see this class has a method called
handleInjections which is annotated with
@PostConstruct which is meant to tell the JVM that once my backing bean has been created this method should be run. When this method is run I just grab the injector I created in my application context and I call injectMembers(this) which will then have a look at what the configure method in the GuiceModule bound and then inject these into my backing bean since we passed in this into the method.
However it will only inject where we have methods annotated with
@Inject. Therefore in the actual backing bean itself I have declared an instance member.
private IUserService userService;
With this I have a setter method.
@Inject
public void setUserService(final IUserService userService) {
this.userService = userService;
}
As we can see here the method has the @Inject annotation which tells Guice that it should have a look at this method when I call injectMembers on this class. It checks to see what the method argument is and then looks that up according to what we configured in the configure method. In this case we want something which implements the IUserService interface which in our case will be the UserService class which we bound to the interface class earlier.
After I've done this all I need to do now is just create another backing bean and have it extend the AbstractBackingBean and just add the instance member and the setter to say I want an IUserService and it will automatically inject it for me.
Simples!
I know this might be over course for a lot of you on these forums but I just thought I'd share this with you since I found it highly useful. Maybe one day you will as well.
// Json