代码之家  ›  专栏  ›  技术社区  ›  mike

在OSGi参考注释中动态设置目标属性

  •  2
  • mike  · 技术社区  · 7 年前

    article 在…上 Reference target (和相应的属性),我仍然不知道如何检索服务,当 target 已设置 在运行时 (通常在编译时设置目标和属性,并在运行时由SCR评估)。

    假设有三种服务实现定义 @Property(name="type", value="csv") , @Property(name="type", value="xls") @Property(name="type", value="pdf") 分别地

    一位消费者:

    //@Reference(target="(type=%runtime_variable%)")
    Service service;
    

    注释 %runtime_variable% 在运行时自动计算(从设置文件读取)。


    我应该打电话吗 getServiceReferences(Class<S> clazz, String filter) @Activate / @Modified 注释方法,以便在运行时获得正确的服务?

    组件如何。如果我不明确使用 @Reference 并在 @激活 / @已修改 带注释的方法?

    我可以用 @Designate 让我的生活更简单的元类型注释?

    3 回复  |  直到 7 年前
        1
  •  3
  •   Milen Dyankov    5 年前

    那个 article 你已经读过了,7岁了,我不清楚它使用了哪些注释(是的,有几种)。我建议忽略它。今天你最好使用 Declarative Services (DS) 和标准OSGi注释。

    简而言之,有两个重要部分:

    • XML文件 /OSGI-INF 提供/使用服务的捆绑包中的文件夹
    • 服务组件运行时(SCR)-在运行时检查其他捆绑包的捆绑包,如果找到上述XML文件,则负责注册和连接服务。

    虽然可以手动编写XML文件,但它们通常是由 Bnd 或其他使用Bnd的构建工具(如美国 bnd-maven-plugin

    至于接线,当你有

       @Reference(target="(type=pdf)")
       Service service;
    

    现场 service 将自动连接到以下实例之一(是的,可以有多个) Service 在OSGi的服务注册表中注册的与目标过滤器匹配的服务。这是由SCR在运行时完成的。您可以通过使用其PID重新配置组件来在运行时更改目标。您可以通过编程或通过属性文件使用 Configuration Admin .

    这个 @Designate 您提到的注释与另一个称为元类型的OSGi规范有关。它允许您更好地定义配置字段的类型。 Here 您可以阅读更多关于如何将元类型与声明性服务1.3结合使用的内容。

    关于OSGi注释的另一个很好的信息来源是 here (忽略Liferay特定的)


    为了反映您编辑的问题,您有一些选择。一种是获取所有实例:

    @Reference(
     cardinality = ReferenceCardinality.MULTIPLE,
     policy = ReferencePolicy.DYNAMIC,
     policyOption = ReferencePolicyOption.GREEDY
     )
    protected void setService(Service service, Map<String, Object> properties) {
       String type = MapUtil.getString(properties, "type");
       _services.put(type, service);
    }
    

    然后你可以从 _services 按类型映射。另一个是重新配置组件。例如,如果你这样定义它

    @Component(
     configurationPid = "my.component"
    )
    public class MyComponent implements ... {
       @Reference(target="(type=pdf)")
       Service myService;
    }    
    

    my.component.cfg 您在其中指定

    myService.target=(type=somethingElse)
    

    您可以使用配置管理API以编程方式执行相同的操作。

        2
  •  2
  •   Christian Schneider    7 年前

    简单使用

    @Reference
    Service myService;
    

    然后在运行时为组件创建配置,并设置如下过滤器:

    myService.target=(mykey=1)
    
        3
  •  0
  •   Tomasz Szymulewski McDowell    6 年前

    你可以这样做:

    @Property(name = "myService.target", label = "My Service", description = "The target reference for the MyService, e.g. use target=(type=html) to bind to services by type.")
    @Reference(name = "myService")
    private Service myService;
    

    然后可以为组件创建配置文件 com.example.impl.MyComponent.config :

    myService.target="(type\=pdf)"
    

    您还可以使用Apache Felix Web控制台在运行时更改此值( http://localhost:8888/system/console/configMgr ).