如何在请求时指定接口及其类型参数?引用 OSGi DS 中的服务?

发布于 2024-10-21 06:57:35 字数 559 浏览 2 评论 0 原文

我有一个像这样的接口:

interface Foo<T> {
    void doSomethingWith(T t);
}

和一些实现,例如:

class Bar implements Foo<String> {
    void doSomethingWith(String s) {
        // ...
    }
}

class Baz implements Foo<Double> {
    void doSomethingWith(Double d) {
        // ...
    }
}

我有一个 OSGi 服务,需要 Foo 的实例。 (以及另一个需要 Foo 的服务等)。

有没有办法暴露&因此使用声明性服务注入实现?我只能弄清楚如何暴露 Bar & Baz 饰 Foo &不像 Foo 那样和 Foo 分别。

I have an interface like:

interface Foo<T> {
    void doSomethingWith(T t);
}

And some implementations like:

class Bar implements Foo<String> {
    void doSomethingWith(String s) {
        // ...
    }
}

class Baz implements Foo<Double> {
    void doSomethingWith(Double d) {
        // ...
    }
}

I have an OSGi service that needs an instance of a Foo<String> (and another service that needs a Foo<Double>, etc.).

Is there a way to expose & thus inject the implementations using Declarative Services? I can only figure out how to expose Bar & Baz as Foo & not as Foo<String> and Foo<Double>, respectively.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

染年凉城似染瑾 2024-10-28 06:57:35

简而言之,由于类型 Foo 这样的东西.html" rel="nofollow">类型擦除。类型信息丢失。

相反,您可以将 Bar 公开为带有服务属性 typeArg=java.lang.String 的原始 Foo,并在将其注入到使用者时使用过滤器。

另一种方法是引入接口 FooString extends Foo; { }, FooDouble 扩展了 Foo; { } 并使用它们代替 Foo

In short, there is no such thing as Foo<String> at runtime due to the type Type Erasure. The type information is lost.

Instead, you can expose Bar as raw Foo with service property typeArg=java.lang.String and use filter when injecting it to the consumer.

Other way is to introduce interfaces FooString extends Foo<String> { }, FooDouble extends Foo<Double> { } and use them instead of Foo.

七秒鱼° 2024-10-28 06:57:35

在类型 Foo 中,T 被擦除为对象。因此,接口上的方法是

void doSomethingWith(Object t)

当您将 Bar 定义为实现 Foo 时,您最终会得到两个方法,包括编译器生成的采用 Object 类型的合成桥方法。

void doSomethingWith(Object t) {
    doSomethingWith((String)t);
}

但就 OSGi 服务而言,以 Foo 名称注册的服务类型就是 Foo,任何实现它的类都必须有一个 doSomethingWith(Object t) 方法。框架或声明性服务无法(除了定义和使用某些服务属性之外)了解服务实现(例如 Bar)已将 T 定义为字符串。

In the type Foo, T is erased to object. So the method on the interface is

void doSomethingWith(Object t)

When you define Bar as implements Foo<String>, you end up with two methods including the compiler generated synthetic bridge method which takes the type Object.

void doSomethingWith(Object t) {
    doSomethingWith((String)t);
}

But as far as OSGi services are concerned, the type of a service registered under the name Foo is just Foo and any class that implements it must have a doSomethingWith(Object t) method. There is no way (other than you defining and using some service properties) for the framework or Declarative Service to understand the service implementation (e.g. Bar) has defined T to be String.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文