如何在请求时指定接口及其类型参数?引用 OSGi DS 中的服务?
我有一个像这样的接口:
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
有没有办法暴露&因此使用声明性服务注入实现?我只能弄清楚如何暴露 Bar & Baz 饰 Foo &不像 Foo
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简而言之,由于类型 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 rawFoo
with service propertytypeArg=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 ofFoo
.在类型 Foo 中,T 被擦除为对象。因此,接口上的方法是
当您将 Bar 定义为实现 Foo 时,您最终会得到两个方法,包括编译器生成的采用 Object 类型的合成桥方法。
但就 OSGi 服务而言,以 Foo 名称注册的服务类型就是 Foo,任何实现它的类都必须有一个 doSomethingWith(Object t) 方法。框架或声明性服务无法(除了定义和使用某些服务属性之外)了解服务实现(例如 Bar)已将 T 定义为字符串。
In the type Foo, T is erased to object. So the method on the interface is
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.
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.