蓝图:如何检查是否满足可选依赖项?

Ale*_*nov 9 osgi blueprint-osgi

blueprint.xml,我用这种方式声明一个可选的依赖:

<reference id="RepositoryListener"
    interface="ru.focusmedia.odp.server.datastore.api.RepositoryListener"
    availability="optional" />

<bean id="Repository"
    class="ru.focusmedia.odp.server.datastore.jpa.repository.RepositoryImpl">
    <jpa:context property="entityManager" unitname="ODP_Server" />
    <tx:transaction method="*" value="Required" />
    <property name="repositoryListener" ref="RepositoryListener" />
</bean>
Run Code Online (Sandbox Code Playgroud)

RepositoryImpl,我有

public void setRepositoryListener(RepositoryListener repositoryListener) {
    logger.info("Repository listener set");
    this.repositoryListener = repositoryListener;
}
Run Code Online (Sandbox Code Playgroud)

即使没有RepositoryListener可用的服务,Blueprint也会调用此方法,如预期的那样.问题是,我怎么能后检查是否存在一个服务?

    if (repositoryListener != null) {
        repositoryListener.notifyDelete(node);
    } else {
        logger.warn("No repository listener set!");
    }
Run Code Online (Sandbox Code Playgroud)

不起作用,因为repositoryListener不是null,但是蓝图代理.

Hol*_*ins 16

有三种选择.

  • 通常情况下,如果尝试并使用(缺少的)可选服务,您将得到五分钟的延迟,而蓝图等待支持服务出现,然后是a ServiceUnavailableException.因此,一种选择是设置非常短的蓝图超时,并捕获ServiceUnavailableException.
  • 可以说更清晰的选择是使用引用侦听器来监视服务的生命周期.这具有需要额外代码的缺点.
  • 最简单 - 也就是最懒的 - 选项是使用可选的引用列表而不是可选的引用.如果不存在令人满意的服务,则列表将为空.当然,如果存在多种令人满意的服务,您将不得不考虑您想要发生什么.

要设置较短的超时,只需在可选服务引用中添加一个属性:

<reference
    id="someReference"
    interface="org.some.service.ServiceInterface"
    availability="optional"
    timeout="100" />
Run Code Online (Sandbox Code Playgroud)

要使用引用侦听器,您需要在蓝图xml中添加以下内容(在Enterprise OSGi in Action的第6章中有更详细的示例和讨论):

<reference
        id="someReference"
        interface="org.some.service.ServiceInterface">
        <reference-listener
            ref="someBean"
            bind-method="bind"
            unbind-method="unbind" />
    </reference>
Run Code Online (Sandbox Code Playgroud)

bindunbind方法被称为服务出现和消失(或服务得到添加和删除您参考列表,如果你使用的参考列表).

使用引用列表并不需要代码示例 - 只需使用一个<reference-list元素并确保您的setter方法采用List.