I'm creating a new project using GoogleGuice as DI.
So i create an interface of my DAO:
public interface UserDAO extends DAO<User> {
// Some CRUD methods
}
and an implementation of that:
public class UserDAOImpl implements UserDAO {
// CRUD Methods implementation
}
This is my ApplicationModule class:
public class ApplicationModule extends AbstractModule {
@Override
protected void configure() {
// Tried swap the order without results
bind(UserDAO.class).in(Singleton.class);
bind(UserDAO.class).to(UserDAOImpl.class);
}
}
On my UserService I try this:
@Inject
private UserDAO dao;
But my dao is allways null. And, when I call Guice.createInjector(new ApplicationModule())
on UserService constructor, I got the following stack trace:
Servlet.service() for servlet [Jersey REST Service] in context with path [/simple-rest-application] threw exception [A MultiException has 2 exceptions. They are:
1. com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for br.com.brunots.training.simple_rest_application.dao.UserDAO was bound.
Did you mean?
br.com.brunots.training.simple_rest_application.dao.UserDAO bound at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:15)
at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:14)
2) A binding to br.com.brunots.training.simple_rest_application.dao.UserDAO was already configured at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:15).
at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:14)
2 errors
2. java.lang.IllegalStateException: Unable to perform operation: create on br.com.brunots.training.simple_rest_application.services.UserService
] with root cause
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for br.com.brunots.training.simple_rest_application.dao.UserDAO was bound.
Did you mean?
br.com.brunots.training.simple_rest_application.dao.UserDAO bound at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:15)
at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:14)
2) A binding to br.com.brunots.training.simple_rest_application.dao.UserDAO was already configured at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:15).
at br.com.brunots.training.simple_rest_application.guice.ApplicationModule.configure(ApplicationModule.java:14)
2 errors
Someone knows what's happening? What I'm missing?
Basically your issue is that you're trying to bind an interface to a singleton without providing any implementation. Then in your "answer", you actually do something better: you provide an interface with an implementation, then you say that your implementation is a singleton. But then you fail to actually make the UserDAO
an effective singleton because you create a new injector for each UserService
.
Try the following:
ApplicationModule.java
public class ApplicationModule extends AbstractModule {
@Override protected void configure() {
bind(UserDAO.class) // Define UserDAO
.to(UserDAOImpl.class) // as implemented by UserDAOImpl
.in(Singleton.class); // and make it a singleton.
}
}
UserService.java
public class UserService {
private final UserDAO userDAO;
@Inject UserService(UserDAO userDAO) { // Actually inject your UserDAO!!
this.userDAO = userDAO;
}
}
Main.java
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new ApplicationModule());
UserService userService = injector.getInstance(UserService.class);
}
}