如何在不同的捆绑包中以及在一个中心OSGi服务下实现和注册接口?

如何在不同的捆绑包中以及在一个中心OSGi服务下实现和注册接口?,osgi,bundles,Osgi,Bundles,我有一个关于在捆绑包之间在OSGi中注册/使用服务的问题。我有两个Bundle,Bundle A—我的核心服务将多个“处理程序”绑定到一个映射(类似于工厂)和Bundle B—它实现了额外的处理程序接口 我的期望是,其他Bundle可以实现接口,并且可以向Bundle A中的单个服务注册,以便在调用该核心服务时,可以查找适当的处理程序并对其进行处理。我希望处理程序的实现由其他bundle提供 我正在研究这个例子: 使用SCR注释的多基数OSGI@引用 “.” 在核心包中,我的处理程序实现正确绑定

我有一个关于在捆绑包之间在OSGi中注册/使用服务的问题。我有两个Bundle,Bundle A—我的核心服务将多个“处理程序”绑定到一个映射(类似于工厂)和Bundle B—它实现了额外的处理程序接口

我的期望是,其他Bundle可以实现接口,并且可以向Bundle A中的单个服务注册,以便在调用该核心服务时,可以查找适当的处理程序并对其进行处理。我希望处理程序的实现由其他bundle提供

我正在研究这个例子:

使用SCR注释的多基数OSGI@引用 “.”

在核心包中,我的处理程序实现正确绑定。在我的其他捆绑包中,服务是通过不绑定到核心服务来注册的

所以,我的问题是,我可以像这样注册捆绑包A中其他捆绑包中的和接口的不同实现吗

捆绑包A-处理程序服务:

@Component
@Service(value = IContentService.class)
public class ContentService implements IContentService
{
    @Reference(
        referenceInterface = IContentHandler.class,
        cardinality = ReferenceCardinality.MANDATORY_MULTIPLE,
        bind = Constants.OSGI_BIND_METHOD,
        unbind = Constants.OSGI_UNBIND_METHOD,
        policy = ReferencePolicy.DYNAMIC)
    private final Map<String, IContentHandler> handlers = Maps.newHashMap();


    protected void bind(final IContentHandler handler)
    {
        final Content h = handler.getClass().getAnnotation(Content.class);
        if (h != null)
        {
            final String id = getHandlerId(h);
            this.handlers.put(id, handler);
        }
    }
@Component
@Service(value = IContentHandler.class)
@Content(name = "bean")
public class BeanContentHandler implements IContentHandler
{
    public IContentBean process(final Resource resource, final ContentOptions options) throws ContentException
    {
        ...
@Component
@Service(value = IContentHandler.class)
@Content(name = "sample")
public class SampleHandler implements IContentHandler
{
    @Override
    public IContentBean process(Resource resource, ContentOptions options) throws ContentException
    {
        ...
捆绑包B-处理程序实现(不注册):

@Component
@Service(value = IContentService.class)
public class ContentService implements IContentService
{
    @Reference(
        referenceInterface = IContentHandler.class,
        cardinality = ReferenceCardinality.MANDATORY_MULTIPLE,
        bind = Constants.OSGI_BIND_METHOD,
        unbind = Constants.OSGI_UNBIND_METHOD,
        policy = ReferencePolicy.DYNAMIC)
    private final Map<String, IContentHandler> handlers = Maps.newHashMap();


    protected void bind(final IContentHandler handler)
    {
        final Content h = handler.getClass().getAnnotation(Content.class);
        if (h != null)
        {
            final String id = getHandlerId(h);
            this.handlers.put(id, handler);
        }
    }
@Component
@Service(value = IContentHandler.class)
@Content(name = "bean")
public class BeanContentHandler implements IContentHandler
{
    public IContentBean process(final Resource resource, final ContentOptions options) throws ContentException
    {
        ...
@Component
@Service(value = IContentHandler.class)
@Content(name = "sample")
public class SampleHandler implements IContentHandler
{
    @Override
    public IContentBean process(Resource resource, ContentOptions options) throws ContentException
    {
        ...

除非(1)bundle B没有从bundle A导入(通过
导入包
)接口(通过
导出包
)或(2)DS实现执行某种代理,使注释消失,否则您的设置看起来正常。您能检查或发布您的清单文件以验证(1)吗?有趣的是,您会提到代理。我切换到使用iPOJO来查看发生了什么,绑定在捆绑包中工作得很好,但是如果抽象类在一个捆绑包中,而实现在另一个捆绑包中,JCROM注释就会失败。注意,我有三个捆绑包——a:Commons(API)、B:Impls和C:Impls。A:Commons:导出接口。B:Impls:Imports A Commons C:Impls:Imports A Commons我在这里质疑注释的使用:如果服务的用户需要注释(在本例中是
内容
注释),它应该是接口的一部分或服务属性的一部分。在这种情况下,我会选择服务属性。这自动解决了代理(如果有的话)的问题。事实上,这个注释是我最不关心的,而且似乎工作得很好。所讨论的注释是JCROM映射注释。当在bundle之间分离时,只有派生类注释是本机的,其余的似乎是代理的。