Osgi guice-运行时选择不同的提供程序
我想在不停止JVM的情况下更改运行时使用的提供程序。例如,这不是我正试图做的,但是这个想法是一样的:比如,我想在运行的应用程序中间从Amazon S3切换到谷歌云存储。 这是我可以在guice内做的事吗 我必须在运行时提供所有JAR,并在启动时配置所有模块。然后,在应用程序启动之后,我必须使用一个提供程序来确定要注入@startup的实例,以及稍后它发生变化的时间 或者,在更新配置后重新启动应用程序是否更好,然后系统将继续该配置,如果需要更改,应用程序将再次需要重新启动Osgi guice-运行时选择不同的提供程序,osgi,guice,Osgi,Guice,我想在不停止JVM的情况下更改运行时使用的提供程序。例如,这不是我正试图做的,但是这个想法是一样的:比如,我想在运行的应用程序中间从Amazon S3切换到谷歌云存储。 这是我可以在guice内做的事吗 我必须在运行时提供所有JAR,并在启动时配置所有模块。然后,在应用程序启动之后,我必须使用一个提供程序来确定要注入@startup的实例,以及稍后它发生变化的时间 或者,在更新配置后重新启动应用程序是否更好,然后系统将继续该配置,如果需要更改,应用程序将再次需要重新启动 OSGI能帮上忙吗?你不
OSGI能帮上忙吗?你不需要任何额外的东西:Guice可以开箱即用。但是您必须使用而不是直接实例 在您的模块中
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
}
}
某处
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
}
}
类切换CloudProvider实现提供程序{
@注入@Named(“谷歌”)提供商googleCloudProvider;
@注入@Named(“amazon”)提供者amazonCloudProvider;
@注入配置;//用作交换机“指挥官”
公共云get(){
开关(configuration.getCloudName()){
案例“google”:返回googleCloudProvider.get();
案例“amazon”:返回amazonCloudProvider.get();
违约:
//不管你想要什么,通常都是例外。
}
}
}
或在模块中的提供程序方法中
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
}
}
@提供
云提供云(
@命名(“谷歌”)提供商google CloudProvider,
@命名(“亚马逊”)提供商amazonCloudProvider,
配置(配置){
开关(configuration.getCloudName()){
案例“google”:返回googleCloudProvider.get();
案例“amazon”:返回amazonCloudProvider.get();
违约:
//不管你想要什么,通常都是例外。
}
}
用法
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
}
}
class-Foo{
@injectprovider cloudProvider;//不要直接注入云,否则在出现更改时将无法获得更改。
公共空白栏(){
Cloud=cloudProvider.get();
//使用云
}
}
您不需要任何额外的东西:Guice可以开箱即用。但是您必须使用而不是直接实例
在您的模块中
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
}
}
某处
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
}
}
类切换CloudProvider实现提供程序{
@注入@Named(“谷歌”)提供商googleCloudProvider;
@注入@Named(“amazon”)提供者amazonCloudProvider;
@注入配置;//用作交换机“指挥官”
公共云get(){
开关(configuration.getCloudName()){
案例“google”:返回googleCloudProvider.get();
案例“amazon”:返回amazonCloudProvider.get();
违约:
//不管你想要什么,通常都是例外。
}
}
}
或在模块中的提供程序方法中
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
}
}
@提供
云提供云(
@命名(“谷歌”)提供商google CloudProvider,
@命名(“亚马逊”)提供商amazonCloudProvider,
配置(配置){
开关(configuration.getCloudName()){
案例“google”:返回googleCloudProvider.get();
案例“amazon”:返回amazonCloudProvider.get();
违约:
//不管你想要什么,通常都是例外。
}
}
用法
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
}
}
class-Foo{
@injectprovider cloudProvider;//不要直接注入云,否则在出现更改时将无法获得更改。
公共空白栏(){
Cloud=cloudProvider.get();
//使用云
}
}
好的,这是有道理的。这是个好主意吗?我想我实现它的方法是避免将自己限制在2或3个,等等。我想我可以在这里使用multibinder查找每个实现,然后通过从列表中选择与配置匹配的正确实现(或在该点引发异常)来确定我想要哪个实现。@WalterWhite是的,这是个好主意,在这里使用多重绑定也很好。考虑到问题中的任何内容都不允许我在Guice中评估您的级别,我不认为最好将其提出来,但是是的,如果您现在能够做到这一点,多绑定完全是最好的工具。我在这里只强调,如果某个云具有非单例作用域,您需要使用Provider
s来避免意外。因此,您应该插入一个映射
。注意,这只在Guice 4之后才起作用。好的,这是有意义的。这是个好主意吗?我想我实现它的方法是避免将自己限制在2或3个,等等。我想我可以在这里使用multibinder查找每个实现,然后通过从列表中选择与配置匹配的正确实现(或在该点引发异常)来确定我想要哪个实现。@WalterWhite是的,这是个好主意,在这里使用多重绑定也很好。考虑到问题中的任何内容都不允许我在Guice中评估您的级别,我不认为最好将其提出来,但是是的,如果您现在能够做到这一点,多绑定完全是最好的工具。我在这里只强调,如果某个云具有非单例作用域,您需要使用Provider
s来避免意外。因此,您应该插入一个映射
。请注意,这仅在Guice 4之后起作用。