我正在尝试使用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 ;;我的问题是:
或者我可以做一些奇怪的事情,比如在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;
}
}
或者也许有一个&#34;实用工具包&#34;只是纯粹的垃圾?
感谢您的回复。希望我能以最清晰的方式传达我的问题
答案 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)。
我不确定喜欢哪种变体。