将现有的Java应用程序修改为OSGi服务

3

我对OSGi和相关技术还很陌生。

问题是这样的:我有一个服务器类,它维护着一个监听器列表。监听器可以通过一个方法 (register(this)) 来注册自己,这个方法会将监听器添加到上述列表中(当然,所有的监听器都必须实现服务器类的监听器接口):

public void register(ServerListener listener) {
    if(theListeners == null)
        theListeners = new ArrayList<ServerListener>();

    theListeners.add(listener);
}

那是一个名为ServerListener的接口:
public interface ServerListener {
    public void update(JsonObject data);
}

现在,服务器类通过一个update(JsonObject object)方法不时地向监听器提供新数据。

public void updateListeners() {
    new Thread() {
        public void run() {
            for(ServerListener l : theListeners) {
                l.update(jsonObject);
            }
        }
    }.start();
}

现在,我想将服务器类修改为OSGi框架(Knopflerfish)中的服务包。我对此完全不熟悉。我只是想试试玩玩,但我现在的做法行不通,因为监听器实际上并不知道它们应该实现ServerListener接口。所以服务器无法通过接口注册它们。
问题是,我希望服务器推送数据,而不是客户端拉取数据(在我的理解中这样会更容易)。有没有人(能够理解我说得不好的解释)指点我正确的方向?

听众实际上不知道他们应该实现ServerListener接口。那么你怎么称呼他们呢? - Thilo
在当前的实现中,侦听器实现接口是行得通的。如果现在另一个开发人员使用他的客户端实现想要从服务器获取数据,他应该以某种方式实现serverlistener接口(对吗?),但是该接口应该在哪里指定/放置呢?在服务器包中不是正确的地方。我需要像核心捆绑包这样的东西,在其中指定此类通用接口和类吗?但无论如何,新客户端也不能访问在另一个包中指定的接口,对吗? - nyyrikki
2个回答

6
“以OSGi为中心”的方法是使用称为白板模式的模式,而不是像普通Java一样使用侦听器模式。您的侦听器不是向服务器类注册,而是作为服务向OSGi服务注册表注册。这意味着框架会处理注册、注销和消失的侦听器。
这里有一份免费的白板模式白皮书: http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf,我们在Enterprise OSGi in Action第5章中也对其进行了讨论(http://www.manning.com/cummins)。
理解侦听器模式可能需要一些时间,因为它是您的侦听器提供服务,而您的“服务器”消耗服务,一开始感觉有些反常。但一旦适应了,它就能很好地工作。您的服务器消耗实现ServiceListener接口的所有服务,并根据需要向它们推送数据。
最好不要直接使用OSGi API来注册和消耗服务-使用声明性服务(SCR)或蓝图来注入OSGi服务的依赖项。这使您可以使用XML元数据文件或注释注册和消耗服务。
(正如其他人建议的那样,使用ServerListener接口的包级依赖关系应该允许它被服务器和侦听器捆绑包导入,无论哪个捆绑包导出了该包。)”

4
你有多个问题:
1. 你需要公开一个服务(服务器类),以便其他对象可以注册。 2. 感兴趣的对象需要找到该服务才能注册自己。 3. 其他对象需要实现特定的接口才能正常工作。
一般来说,如果没有模块化架构,将现有代码改为OSGi可能会很困难。
监听器接口可以存在于服务器包中,或者您可以将其放在单独的API/合同包中-这两种都是有效的设计。
从您描述问题的方式来看,似乎您不知道OSGi中可以有哪些类型的依赖关系。
从传统的Java开发中来看,大多数开发人员都会从“我的依赖关系基于JAR”开始-这不是最佳模型。
OSGi提供了基于包的依赖项。通过这种方式,只要某个捆绑包提供所需的包,您的捆绑包就不必关心哪个捆绑包/JAR提供了依赖项。
因此,如果您为侦听器接口使用包级别的依赖项,则实现不需要关心它是来自服务器包还是合同/API包。
最后请注意,您的设计将服务器与侦听器紧密耦合。如果侦听器失败或挂起,会发生什么?发布/订阅是这种类型通信的更好模型。
*编辑*
Holly的答案再次提醒我白板模式-绝对是一个好主意。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接