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

时间:2016-06-27 08:42:30

标签: java osgi aem

我有业务要求,作为某些处理的一部分,我们为外部管理的代码启用“插件”功能。

决定最好的方法是@Reference一个“排名”列表(根据不相关的算法排序)服务。或多或少是这样的:

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. 抓取所有已安装的捆绑包及其从捆绑包标题中获取的元xml,寻找服务定义 - 这是......嗯,这很费时,一开始。

  3. grep通过日志寻找服务注册和/或失败 - 这个似乎只是......错了。

  4. 上述任何一种解决方案都是正确的吗?有更好的解决方案吗?我怎么能解决这个问题?我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

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

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

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