osgi - 如何动态更新 OSGi 组件中的引用?

标签 osgi apache-felix

我有一个 OSGi 组件 MyComponent .

该组件引用了服务 MyService .现在MyService有几个实现 MyServiceImpl1MyServiceImpl2 . MyComponent还有房产MyProperty .

现在我想要的是每当MyProperty是 1,MyComponent.MyService绑定(bind)到 MyServiceImpl1 .如果我改变 MyProperty到 2, MyComponent.MyService动态更新MyService绑定(bind)到`MyServiceImpl2。

我如何实现这一目标?作为引用,我使用的是 Apache Felix 容器,并且希望避免使用较低级别的 OSGi api。

最佳答案

配置依赖项的最简单方法是使用“.target”属性。这要求实现注册一个识别属性,比如说 impl=1 .和 impl=2 .

@Component(property="impl=1")
public class MyServiceImpl1 implements MyService {
}
@Component(property="impl=2")
public class MyServiceImpl2 implements MyService {
}

然后该组件可能如下所示:
@Component
public class MyComponent {
    @Reference(target="(impl=1)")
    volatile MyService myService;
}

在这种情况下,您将无法使用 1 或 2 作为标志,但您必须修改 MyComponent 的配置属性。名称为 myService.target与另一个过滤器。 (这与 OSGi 标准化注释一起显示。)

如果您坚持 select 的属性为 1 或 2(我们称之为 MyComponent )然后它更详细。首先,我们有满足的问题。根据选择属性 impl 1 需要 MyComponent 但只有 2 可用时是否应该满足?如果没问题,那么以下更复杂的解决方案应该可以工作
@Designate( ocd=Config.class )
@Component( property = "select=1" )
public class MyComponent {
      static Class<?> types [] = {
          MyServiceImpl1.class,
          MyServiceImpl2.class,
      };
      @interface Config {
          int select() default 1;
      }

      @Reference(target="(|(impl=1)(impl=2))")
      volatile List<MyService> candidates;

      volatile MyService selected;

      @Activate
      @Modify
      void changed( Config config ) {
          Class<?> type = types[config.select()];
          Optional<MyService> service = candidates.
              stream().
              filter( type::isInstance ).
              findFirst();
          this.service = service.isPresent() ? service.get() : null;
      }
}

正如您所看到的,组件开始处理自己的依赖项通常是一个坏主意。因此,我对您的真实世界场景感到好奇。

我发现在组件对引用对象挑剔的情况下,维护设计总是非常尴尬和困难。有时这是不可避免的,但在一般解决方案中,MyServiceImpl2MyServiceImpl1根据一些条件决定是否注册更好地反射(reflect)现实。

所以我最大的问题是 1 或 2 属性在现实世界中反射(reflect)了什么?这不能被建模为服务依赖吗?

(免责声明:代码未经测试且没有错误处理)

关于osgi - 如何动态更新 OSGi 组件中的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37940008/

相关文章:

java - Maven - Unresolved 对 [javax.activation, javax.annotation] 的引用

osgi - 设置 osgi.configuration.area 破坏了我的 Equinox OSGI 应用程序

java - 在 Android 中使用模块化

OSGI:当调用一个已经很忙的服务时会发生什么?

OSGi 上的 java.lang.NoClassDefFoundError

osgi - 如何更改 Felix gogo shell 中的默认命令范围?

java - 无法从 dev.eclipse.org cvs 导入项目

java - 我应该将共享测试实用程序放在多模块 Maven 项目中的什么位置?

java - OSGi:如何获取其他包的类加载器

java - Weld-osgi-bundle-2.2.10.Final 无法解析 sun.misc