让我们声明“所有岩石都有矿物质。
”:
public class Mineral
{
// Nevermind why a Mineral would have a GUID.
// This is just to show that each Mineral instance
// is universally-unique.
String guid;
@Inject
public Mineral(String id)
{
guid = id;
}
}
public class Rock
{
private Mineral mineral;
@Inject
public Rock(Mineral min)
{
mineral = min;
}
}
如果我们想要 2 个 Rock
实例,每个实例都配置有不同的 Mineral
实例(每个实例都有自己的 GUID):
public class RockModule extends AbstractModule
{
public void configure(Binder binder)
{
// Make two Minerals with different GUIDs.
Mineral M1 = new Mineral(UUID.getRandomId().toString());
Mineral M2 = new Mineral(UUID.getRandomId().toString());
// Configure two Rocks with these unique Minerals
Rock R1 = new Rock(M1);
Rock R2 = new Rock(M2);
// Define bindings
bind(Rock.class).toInstance(R1);
// No way for Guice to expose R2 to the outside world!
}
}
现在,当我们向 Guice 请求 Rock
时,它总是会为我们提供 R1
实例,该实例本身配置有 M1
> Mineral
的实例。
在 Spring DI 中,您可以将两个 bean 定义为相同类型,但只需为它们提供不同的 bean ID 即可。然后,您可以使用 Bean 的 ID 将它们“连接”在一起。所以我可以将R1
和M1
连接在一起,将R1
和M2
连接在一起,等等。然后,我可以问Spring对于 R1
或 R2
,因为我需要它们。
使用 Guice,您只能请求您想要的类型 (Rock.class
),而不是实例。
如何通过 Guice 请求不同的“有线 bean ”?通过使用不同的AbstractModule
具体?或者这是 Guice 的限制?
最佳答案
通常这会违反 Guice 的建议。您通常不会在模块内new
类来创建实例,因为这首先违背了使用 DI 容器的目的。 (为什么要使用 @Inject
注释你的类?)
相反,你应该让 Guice 为你做这件事:
class RockModule extends AbstractModule {
public void configure() {}
@Provides
@Named("UUID")
public String getUuid() {
return UUID.getRandomId().toString();
}
}
现在,每个Mineral
都会自动获得一个唯一的UUID,每个Rock
都会获得一个唯一的Mineral
。
这让我们分道扬镳,但如果你想要在运行时使用岩石和矿物的两个独特配对,那么这就是 Guice 所说的“机器人腿”问题,你可以使用私有(private)模块来解决它。查看示例 here .
关于java - Guice:请求实例,而不是类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10141544/