Java 屋宇署;注射客户端

Java 屋宇署;注射客户端,java,language-agnostic,inversion-of-control,guice,Java,Language Agnostic,Inversion Of Control,Guice,我有一个第三方数据库客户端,我想让Guice创建和管理它的一个单例实例,然后注入它 我知道使用Guice可以注入一个“对象”,在本例中,它是一个使用接口和实现的db客户机。但是有没有可能像spring允许的那样让Guice直接创建并提供singleton db客户端?不太确定“直接创建”部分,但至少有两个选项可以创建singleton: 1。对实施进行注释 interface DbClient { } @Singleton class DbClientImpl implements DbCli

我有一个第三方数据库客户端,我想让Guice创建和管理它的一个单例实例,然后注入它


我知道使用Guice可以注入一个“对象”,在本例中,它是一个使用接口和实现的db客户机。但是有没有可能像spring允许的那样让Guice直接创建并提供singleton db客户端?

不太确定“直接创建”部分,但至少有两个选项可以创建singleton:

1。对实施进行注释

interface DbClient {
}

@Singleton
class DbClientImpl implements DbClient {
}

class DbClientModule extends AbstractModule {
  @Override public void configure() {
    bind(DbClient.class).to(DbClientImpl.class);
  }
}
interface DbClient {
}

class DbClientImpl implements DbClient {
}

class DbClientModule extends AbstractModule {
  @Override public void configure() {
    bind(DbClient.class).to(DbClientImpl.class).in(Singleton.class);
  }
}
2。作为单例绑定

interface DbClient {
}

@Singleton
class DbClientImpl implements DbClient {
}

class DbClientModule extends AbstractModule {
  @Override public void configure() {
    bind(DbClient.class).to(DbClientImpl.class);
  }
}
interface DbClient {
}

class DbClientImpl implements DbClient {
}

class DbClientModule extends AbstractModule {
  @Override public void configure() {
    bind(DbClient.class).to(DbClientImpl.class).in(Singleton.class);
  }
}
就我个人而言,我更喜欢第二个选项,因为它允许将同一个类作为单例使用,或者不依赖于上下文

编辑:由另一个库创建的对象

没问题。下面是您如何处理的:

class DbClientModule extends AbstractModule {
  @Override public void configure() {
    DbClient client = AnotherLibrary.createDbClient();
    bind(DbClient.class).toInstance(client);
  }
}
编辑2:如果我要提供的对象无法立即使用,该怎么办?

也没问题。以下是我们可以做的:

public static void main(String[] args) {
  DbClient client = SomeWeirdPlace.getDbClient();
  Injector injector = Guice.createInject(new MyModule(client));
  injector.getInstance(ServerInterface.class).start();
}

class MyModule extends AbstractModule {
  MyModule(DbClient client) {
    this.client = client;
  }
  @Override public void configure() {
    bind(Client.class).toInstance(client);
  }
}

我有一个第三方db客户机,我想创建它的单例实例,并通过guice注入它。使用上述任何一种方法,我基本上是围绕第三方客户机创建一个工厂包装器。有没有一种方法可以让Guice创建一个单例实例并在注释的地方进行注入呢?您更新的答案几乎正是我所需要的。经过进一步研究,我了解到使用“@Provides”可以创建一种方法,根据需要生成所需的对象。然而,剩下的唯一问题是,我需要向“@Provides”方法传递一个对象,该对象是在引导时由底层框架创建的。您知道如何将对象传递给AbstractModule实现中的方法吗?@iluxa,不要在
configure()
内部进行任何复杂的调用,如
AnotherLibrary.createDbClient()
!这肯定会导致隐藏的错误消息和意外的异常
@Provides
-应改用方法或
提供程序
.@Ari,如果您的数据库客户端有“一个对象作为依赖项在引导时由底层框架创建”,则您也可以通过Guice管理该对象(例如,通过定义另一个
@Provides
-方法)inject是作为返回DB客户端的
@提供的
-方法的参数。首先,你说的引导对象是什么意思?你必须以某种方式创建任何对象,无论是构造函数调用还是工厂方法。因此,你几乎总是可以创建
提供程序
@提供的
-方法来创建所有必需的对象如果由于某种原因无法编写提供程序,可以将对象传递给模块构造函数并创建
toInstance()
绑定。