2016-09-14 56 views
2

我试图用OSGi框架开发一个简单的应用程序。我的问题涉及框架中的“实用程序包”:让我用一个相当详细的例子来解释。目前我正在尝试构建一个我的包将发送的事件。创建一个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应用程序可以有很多的包,我想创建事件的子类对于每个包(例如,我有一个名为“BundleExample”的包?在其导出的类中将会有一个“BundleExampleEvent”)。我知道这不会添加任何信息,因为你可以通过查看“主题”知道你收到了哪个事件,但请暂时与我联系

现在,Event构造函数需要一个主题和Map<String, Object>。但是,为了“简化”事件构造函数,我只想将主题和参数列表放入地图中。例如,以下是可能是什么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在构造函数中,但我不想这样做,因为这是非常愚蠢的东西将取决于一个“实用工具类”;我的问题是:

  1. 如果我想要一个“实用程序包”,这是唯一可用的方法吗?
  2. 或者我可以做一些奇怪的事情,比如在我的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; 
        } 
    } 
    
  3. 或者,也许有一个“工具包”的整体思路是只是纯粹的垃圾?

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

回答

3

我不认为Utils是一项服务。事情应该只是一个服务,如果他们可以想象有多个实现。在你的情况下,Util功能的消费者只想要单个实现...实现的合同。

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

+1

静态链接是一个很好的概念,但我认为它不是很好理解用户。它也花了我一段时间来了解如何以及在何处使用它。也许值得一个博客条目,如果你还没有一个:-) –

+0

@ChristianSchneider我做到了! http://njbartlett.name/2014/05/26/static-linking。html –

+0

这就是我所希望的:-)谢谢 –

2

在你的情况下,Utils utils将是一个OSGi服务。然后,您想在不是像BundleExampleEvent这样的服务的对象内使用此服务。

你可以做的是创建一个服务,创建BundleExampleEvent实例并将其与OSGi服务一起提供。有点像工厂作为服务。问题在于OSGi中的服务是动态的。如果BundleExampleEvent实例所需的服务消失,则该对象将不得不被丢弃。所以这只适用于短暂的对象。

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

我不确定哪个变体更喜欢。

+0

从我的理解,为了避免把Utils的引用放入构造函数中,我需要为此唯一目的创建另一个服务。听起来像很多代码几乎没有。我认为我的最佳选择是在构造函数中传递Utils实例或放弃Utils包。在你看来,哪一个是OSGi友好的选择?我是OSGi n00bie,所以我不确定最佳解决方案。谢谢! – Koldar

+0

如果您的Utils类不需要服务或具有静态方法,那么就像使用纯java一样使用它。你不需要注入它。所以你可以在你的事件对象中调用这样的方法,而不用任何构造器注入。 Btw。我不确定是否建议使用专门的Event类。至少我从来没有见过它。 –

+0

我认为专门的事件是事实上没用的......你从专门化他们得到的唯一东西是一些getter和setter。关于实用程序类...我不确定,因为如果实用程序类中存在缺陷,解决此问题的唯一方法是手动停止该框架,更新该类并重新启动它;如果它是一个OSGi注入包,我可以只更新它自己的包。我认为在这里我们处于一种易于编码 - 健壮性的折衷方案。你有没有看到公用类捆绑?只是为了了解我的解决方案是否已被其他人使用! – Koldar

相关问题