java - 使用 DS 多次实例化 Bundle

标签 java osgi equinox e4 declarative-services

我正在创建一个包含大量 bundle 的应用程序。其中一些是接口(interface),一些是这些接口(interface)的实现。我使用声明性服务 (DS) 来提供和使用服务,这意味着每个 bundle 都有一个描述我提供/引用的服务的 component.xml。

目前我有一个名为 ClockWidget 的类,它实现了 3 个接口(interface)(如附图所示)。对于实现的每个服务,我都有一个引用该服务的特定类。例如,Timeout 类具有接收任何实现 TimeoutListener 服务的绑定(bind)方法。 enter image description here

问题在于 ClockWidget 类的构造函数被调用了 3 次。显然,我将其与其他 bundle 使用的服务数量联系起来。

问题是:处理实现多个服务的 bundle 有什么好的方法/实践?我的意思是,我不希望这个包在应用程序中重复。我想在引用这个人的三个类中使用相同的实例。我尝试在 list 中启用单例属性,但没有任何改变。

ClockWidget.class:

public class ClockWidget implements Widget, TimeoutListener, DummyInterface {

    public ClockWidget() {
        System.out.println("ClockWidget constructor.");
    }

    @Override
    public String getWidgetName() {
        return "Clock widget";
    }

    @Override
    public void onTimeout() {
        System.out.println("Timeout!");
    }

    @Override
    public void dummyMethod() {
        // Does nothing.
    }
}

其组件定义ClockWidget.xml

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="test.e4.ClockWidget">
   <implementation class="test.e4.history.ClockWidget"/>
   <service>
      <provide interface="test.e4.widget.Widget"/>
      <provide interface="test.e4.timeoutlistener.TimeoutListener"/>
      <provide interface="test.e4.dummyinterface.DummyInterface"/>
   </service>
</scr:component>

使用ClockWidget提供的服务的类。在本例中,Timeout 类:

public class Timeout {

    private ArrayList<TimeoutListener> listeners;

    public Timeout() {
        listeners = new ArrayList<>();
        startTimeoutTimer();
    }

    public void startTimeoutTimer() {
        long timeoutInMs = 60 * 1000;
        Timer timeoutTimer = new Timer();
        timeoutTimer.schedule(new TimerTask() {

            @Override
            public void run() {
                timeout();
            }
        }, timeoutInMs);
    }

    // Bind method from DS
    public void addListener(TimeoutListener listener) {
        listeners.add(listener);
    }

    // Unbind method from DS
    public void removeListener(TimeoutListener listener) {
        listeners.remove(listener);
    }

    public void timeout() {
        for (TimeoutListener listener : listeners) {
            listener.onTimeout();
        }
    }
}

超时组件说明:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="test.e4.Timeout">
   <implementation class="test.e4.Timeout"/>
   <reference bind="addListener" cardinality="0..n" interface="test.e4.timeoutlistener.TimeoutListener" name="TimeoutListener" policy="dynamic" unbind="removeListener"/>
</scr:component>

有什么建议吗?

最佳答案

ClockWidget是注册在3个服务名称下的一个DS组件吗?或者 3 个 DS 组件,每个组件都注册在一个服务名称下。如果是后者,那么是的,ClockWidget 将为每个服务实例化一次,因为 DS 只知道这一点。如果是前者,那么 ClockWidget 应该只实例化一次,因为它是在 3 个服务名称下可用的单个服务。

关于java - 使用 DS 多次实例化 Bundle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23902577/

相关文章:

osgi - 如何启动 osgi 控制台 (Equinox)

java - 在编码之前我是否需要传入要绑定(bind)在 JAXBContext 中的所有类

java - 在 Netbeans 中禁用 Maven 依赖项解析提示

Java泛型问题

java - 如何将 JSF 扩展库用作 OSGI 包

java - 如何避免 karaf 加载默认解析包

java - 从什么时候开始在 Java 中必须包含一个空的构造函数?

osgi - 如何在 OSGi 容器中的包之间共享非 OSGi 库?

java - OSGI容器识别Equinox/knopflerfish以及Equinox osgi jar和核心osgi jar之间的关系

java - 在父应用程序和 OSGi 框架之间传递参数