我想更改我在运行时使用的提供程序,而不必停止JVM。例如,这并不是我试图做的事情,但这个想法是一样的:比如说,我想在正在运行的应用程序中间从Amazon S3切换到Google Cloud存储。
我能在guice中做些什么吗?
我必须在运行时使用所有jar并在启动时配置所有模块。然后,稍后在应用程序启动后,我必须使用一个提供程序,该提供程序可以确定将哪个实例注入@启动,以及稍后何时更改。
或者,更新配置后重新启动应用程序会更好,然后系统会继续执行该配置,如果需要更改,则需要重新启动应用程序。
OSGI会帮助吗?
答案 0 :(得分:2)
你不需要任何额外的东西:Guice可以开箱即用。但是......你必须使用Provider
s而不是直接实例。
在您的模块中
bind(Cloud.class)
.annotatedWith(Names.named("google"))
.to(GoogleCloud.class);
bind(Cloud.class)
.annotatedWith(Names.named("amazon"))
.to(AmazonCloud.class);
bind(Cloud.class)
.toProvider(SwitchingCloudProvider.class);
<强>某处强>
class SwitchingCloudProvider implements Provider<Cloud> {
@Inject @Named("google") Provider<Cloud> googleCloudProvider;
@Inject @Named("amazon") Provider<Cloud> amazonCloudProvider;
@Inject Configuration configuration; // used as your switch "commander"
public Cloud get() {
switch(configuration.getCloudName()) {
case "google": return googleCloudProvider.get();
case "amazon": return amazonCloudProvider.get();
default:
// Whatever you want, usually an exception.
}
}
}
或模块中的提供商方法
@Provides
Cloud provideCloud(
@Named("google") Provider<Cloud> googleCloudProvider,
@Named("amazon") Provider<Cloud> amazonCloudProvider,
Configuration configuration) {
switch(configuration.getCloudName()) {
case "google": return googleCloudProvider.get();
case "amazon": return amazonCloudProvider.get();
default:
// Whatever you want, usually an exception.
}
}
<强>用法强>
class Foo {
@Inject Provider<Cloud> cloudProvider; // Do NOT inject Cloud directly or you won't get the changes as they come up.
public void bar() {
Cloud cloud = cloudProvider.get();
// use cloud
}
}