创建osgi实用程序包

时间:2016-09-14 15:28:53

标签: java osgi osgi-bundle

我正在尝试使用OSGi框架开发一个简单的应用程序。我的问题涉及"实用工具包"在框架中可用:让我用一个非常详细的例子来解释。目前我正在尝试建立我的捆绑包将发送的事件。

根据我的理解,我需要做的事情如下(event admin felix):

public void reportGenerated(Report report, BundleContext context)
    {
        ServiceReference ref = context.getServiceReference(EventAdmin.class.getName());
        if (ref != null)
        {
            EventAdmin eventAdmin = (EventAdmin) context.getService(ref);

            Dictionary properties = new Hashtable();
            properties.put("title", report.getTitle());
            properties.put("path" , report.getAbsolutePath());
            properties.put("time", System.currentTimeMillis());

            Event reportGeneratedEvent = new Event("com/acme/reportgenerator/GENERATED", properties);

            eventAdmin.sendEvent(reportGeneratedEvent);
        }
    }

现在,由于OSGi应用程序可能有很多捆绑包,我想为每个捆绑包创建一个Event的子类(例如,我有一个名为&#34的捆绑包; BundleExample"?在其内部导出类将有一个" BundleExampleEvent")。我知道这并没有添加任何信息,因为您可以通过查看" topic"来了解您收到的事件,但请暂时告诉我

现在,Event构造函数需要一个主题和一个Map<String, Object>。然而,为了简化&#34;事件构造函数,我想只有主题和参数列表放在地图中。例如,这里可能是BundleExampleEvent类:

public class BundleExampleEvent extends Event{

    private int importantVariable;

    public BundleExampleEvent(String topic, int importantVariable) {
        super(topic, Utils.toMap("importantVariable", importantVariable));
        //here toMap is static
    }

    public int getImportantVariable() {
        return this.importantVariable;
    }   
}

好的,请注意Utils.toMap:它是一个允许您将String, Object序列转换为Map的函数。好的,现在Utils是一个实用工具类的例子(愚蠢,无用,但实用工具类)。 本着OSGi的精神,我想让这个实用程序类成为一个包:我的想法是在框架启动时启动这个Utils包,然后每当我需要它的一个实用程序我想要获取一个通过@Reference注释引用。

这可以在任何捆绑接口实现中发挥作用,如下所示:

@Component
public class BundleExampleImpl implements BundleExample {
   @Reference
   private Utils utils;

   @Override
   public String sayHello() {
      return this.utils.fetchHello();
      //another useless utility function, but hopefully it conveys what i'm trying to do
   }
}

但是其他类(即在其工作期间由BundleExampleImpl调用)呢?例如BundleExampleEvent怎么样?我需要从sayHello方法调用它,我想在该类中使用此实用程序来计算Map!在前面的例子中我使用了静态函数,但是我想使用OSGi给我的Utils的引用。

当然我可以在BundleExampleEvent的构造函数中添加一个参数以满足链接但我宁愿不这样做,因为它会很愚蠢取决于&#34;实用程序类&#34 ;;我的问题是:

  1. 如果我需要&#34;实用工具包&#34;?
  2. ,这是唯一可用的方法吗?
  3. 或者我可以做一些奇怪的事情,比如在BundleExampleEvent中添加Utils的引用;就像这样:

    public class BundleExampleEvent extends Event{
        @Reference
        private Utils utils;
        private int importantVariable;
    
        public BundleExampleEvent(String topic, int importantVariable) {
            super(topic, Utils.toMap("importantVariable", importantVariable));
            //here toMap is static
        }
    
        public int getImportantVariable() {
            return this.importantVariable;
        }   
    }
    
  4. 或者也许有一个&#34;实用工具包&#34;只是纯粹的垃圾?

  5. 感谢您的回复。希望我能以最清晰的方式传达我的问题

2 个答案:

答案 0 :(得分:3)

我不认为Utils有任何意义上的服务。如果可以想象有多个实现,事情应该只是一种服务。在您的情况下,Util功能的消费者只需要一个实现......实现 合同。

我甚至不认为utils代码应该捆绑在一起。只需将其放入一个静态链接到需要它的包中的库。

答案 1 :(得分:2)

在您的情况下,Utils utils将是OSGi服务。然后,您希望在不是像BundleExampleEvent这样的服务的对象中使用此服务。

您可以做的是创建一个创建BundleExampleEvent实例并使用OSGi服务提供它的服务。有点像工厂作为服务。这个问题是OSGi中的服务是动态的。如果BundleExampleEvent实例所需的服务消失,则必须丢弃该对象。所以这只适用于短期物体。

在eventadmin示例中,另一种解决方案是不使用特殊事件类,而是创建一个具有发送此类事件的方法的服务。然后所有的魔法都会在这个方法中发生,结果将是一个没有进一步逻辑的事件。您还可以使用DS将EventAdmin注入该服务。 这在OSGI中非常有效,但缺点是贫血域模型(http://www.martinfowler.com/bliki/AnemicDomainModel.html)。

我不确定喜欢哪种变体。