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

时间:2011-12-23 09:31:15

标签: java osgi

我对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接口。因此服务器无法通过接口注册它们。

问题是,我想服务器推送数据,而不是客户端拉(根据我的理解,这会更容易)。某人(他理解我的不良解释)能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:6)

'以OSGi为中心'的方法是使用称为白板模式的模式,而不是像普通Java那样使用监听模式。您的侦听器不是使用服务器类注册,而是使用OSGi服务注册表注册为服务。这意味着该框架负责处理注册,注销和听众的处理。

这里有一个关于白板模式的免费白皮书:http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf,我们还在 Enterprise OSGi in Action http://www.manning.com/cummins的第5章中对它进行了讨论。 )。

可能需要一段时间才能让你的头部围绕听众模式,因为它是你的听众提供服务,而你的'服务器'消耗服务,起初感觉倒退。但是,一旦你习惯它,它的效果非常好。您的服务器使用实现ServiceListener接口的所有服务,并根据需要将数据推送到它们。

最好不要直接使用OSGi API来注册和使用服务 - 使用声明性服务(SCR)或蓝图来依赖注入OSGi服务。这些允许您使用XML元数据文件或注释注册和使用服务。

(正如其他人所建议的那样,使用ServerListener接口的包级依赖项应该允许服务器和侦听器包导入它,无论哪个bundle导出包。)

答案 1 :(得分:4)

你在这里遇到了多个问题:

  1. 您需要公开服务(服务器类)以便注册其他对象
  2. 感兴趣的对象需要找到服务才能自行注册
  3. 其他对象需要实现特定的界面才能使其正常工作
  4. 一般来说,尝试将现有代码改装到OSGi中可能会很痛苦,除非您已经拥有模块化架构。

    侦听器接口可以存在于服务器包中,也可以将其放在单独的API /合约包中 - 两者都是有效的设计。

    从描述问题的方式来看,您可能不知道OSGi中可能存在的不同类型的依赖关系。

    来自传统的Java开发,大多数开发人员将从“我的依赖项基于JAR”开始 - 这不是最好的模型。

    OSGi提供包级依赖性。通过这种方式,只要一些bundle提供了所需的包,你就是bundle并不关心哪个bundle / JAR提供了依赖。

    因此,如果您对侦听器接口使用了包级依赖关系,则实现不需要关心它是来自服务器包还是合同/ API包。

    最后一点,您的设计将服务器与听众紧密联系在一起。如果听众失败会怎么样?还是挂? Pub / sub是这种通信的更好模型。

    *编辑*

    霍莉的回答再次提醒我白板模式 - 绝对是个好主意。