如何获得实现给定接口的所有服务,而不仅仅是活动的服务?

How to get all services implementing given interface, not just active ones?

我有一项业务要求,作为某些处理的一部分,我们为 externally-managed 代码启用 "plugin" 功能。

我们决定最好的方法是 @Reference "ranked"(根据不相关算法排序)服务的列表。大致是这样的:

public interface ExternalProcessor {
    void doSomething();
}

@Component
@Service(ImportantTaskManager.class)
public class ImportantTaskManager{

    @Reference(cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, referenceInterface = ExternalProcessor.class)
    protected List<ExternalProcessor> processors;

    public void doImportantStuff(){
        for(ExternalProcessor processor: processors){
            processor.doSomething();
        }
    }
}

为了简短起见,我尽可能多地省略了样板文件,包括 bind/unbind 方法对。

现在,另一个业务需求是,如果有实现 ExternalProcessor 接口的服务未绑定到我们的主处理器(出于任何原因:未解决),我们将不执行任何类型的处理依赖项、激活期间崩溃、缺少必需的配置等)。我感觉这有点违背 OSGi 原则(其中 OSGi 只提供可用服务,而不提供有关不可用服务的信息),但我怎样才能做到这一点?

到目前为止,我提出了以下候选解决方案:

  1. 请外部团队提供我们应该期望的服务数量,然后将其与我们从 OSGi 获得的服务进行比较 - 它不可靠

  2. 爬取所有已安装的捆绑包及其从捆绑包 headers 中获取的元 xml 以查找服务定义 - 它是......好吧,它是 time-consuming,作为开始。

  3. grep 通过日志查找服务注册 and/or 失败 - 这个似乎只是...错误。

以上是否是解决此问题的合适方法?有更好的解决方案吗?我还能如何解决这个问题?我在这里错过了什么?

我对安全插件有类似的要求。当缺少必要的安全插件时,调用插件的代码不应 运行。

我通过定义一个像id这样的服务属性解决了这个问题。每个插件都有一个唯一的 ID。在您的主要代码的配置中,您通过 id 指定您需要的安全插件列表。

代码随后会检查每个服务的 ID,并且仅在存在所有必需插件时才激活主要组件。