Google Guice 注入成员不工作

Google Guice Inject Member not working

我正在使用 GoogleGuice 作为 DI 创建一个新项目。

所以我创建了我的 DAO 接口:

public interface UserDAO extends DAO<User> {

    // Some CRUD methods

}

及其实现:

public class UserDAOImpl implements UserDAO {

     // CRUD Methods implementation

}

这是我的 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);

    }

}

在我的 UserService 上,我尝试这样做:

@Inject
private UserDAO dao;

但我的道总是空的。而且,当我在 UserService 构造函数上调用 Guice.createInjector(new ApplicationModule()) 时,我得到了以下堆栈跟踪:

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

有人知道发生了什么事吗?我缺少什么?

我发现了一些东西...

如果我将 ApplicationModule 更改为:

public class ApplicationModule extends AbstractModule {

    @Override
    protected void configure() {

        bind(UserDAO.class).to(UserDAOImpl.class);
        bind(UserDAOImpl.class).in(Singleton.class);

    }

}

这没有解决问题...我的 UserDAO 仍然没有被注入,但我可以用 Guice.createInjector(new ApplicationModule()) 创建注入器。所以在 UserService 构造函数上我可以做类似的事情:

public UserService() {
    Injector injector = Guice.createInjector(new ApplicationModule());
    injector.injectMembers(this);
}

基本上,您的问题是您试图将接口绑定到单例而不提供任何实现。然后在你的 "answer" 中,你实际上做了更好的事情:你提供了一个带有实现的接口,然后你说你的实现是一个单例。但是你实际上并没有使 UserDAO 成为一个有效的单例,因为你为每个 UserService.

创建了一个新的注入器

尝试以下操作:

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);
  }
}