让我们发表声明“All Rocks have Minerals.
”:
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。然后使用他们的ID“连接”bean。所以我可以将R1
和M1
连接在一起,R1
和M2
,等等。然后,我可以向Spring询问R1
或R2
因为我需要它们。
使用Guice,您只能询问所需的类型(Rock.class
),而不是实例。
您如何使用Guice请求不同的“有线bean”?使用不同的AbstractModule
结核?或者这是Guice的限制吗?
答案 0 :(得分:1)
我怀疑你想要binding annotations。 Guice不会通过类型绑定 - 它通过键绑定 - 但如果你不做任何其他操作,那么键只会包含类型。绑定注释允许您创建更丰富的密钥。
链接文档比我更好地解释了它,但结果是有多种方法可以指定你想要的东西,包括:
@Inject
public Foo(@Named("X") Rock rock)
或
@Inject
public Foo(@HardRockCafe Rock rock)
在后一种情况下,@HardRockCafe
是自定义绑定注释。
答案 1 :(得分:1)
通常这会违反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
。
这让我们分道扬..但是如果你想在运行时使用两种独特的Rock and Mineral配对,那么这就是Guice所说的“机器人腿”问题,你可以使用私有模块解决它即可。查看示例here。