[英]how useful is to create an osgi utility bundle
I'm trying to develop a simple application using OSGi framework. 我正在尝试使用OSGi框架开发一个简单的应用程序。 My question involves an "utility bundle" available in the framework: let me explain with a pretty verbose example.
我的问题涉及框架中可用的“实用程序包”:让我用一个非常详细的示例进行解释。 At the moment I'm trying to build an event my bundle will send.
目前,我正在尝试建立一个捆绑发送的事件。
From what I understood, what i need is to do something like the following ( event admin felix ): 据我了解,我需要做如下事情( 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);
}
}
Now, since an OSGi application may have lots of bundles, I thought to create a subclass of Event for every bundle (eg. I have a bundle named "BundleExample"? Inside it's exported classes there will be a "BundleExampleEvent"). 现在,由于OSGi应用程序可能有很多捆绑包,因此我想为每个捆绑包创建Event的子类(例如,我有一个名为“ BundleExample”的捆绑包?在其导出的类中将有一个“ BundleExampleEvent”)。 I
know this doesn't add any information since you can know which event you received by looking at "topic", but please bear with me for the moment .
我知道这不会添加任何信息,因为您可以通过查看“主题”来了解收到的事件,但是请耐心等待 。
Now, the Event
constructor needs a topic and a Map<String, Object>
. 现在,
Event
构造函数需要一个主题和一个Map<String, Object>
。 However, to "simplify" the event constructor, I would like to have only the topic and the list of parameters to put inside the map. 但是,为了“简化”事件构造函数,我只想将主题和参数列表放入映射中。 For example here's what might be a BundleExampleEvent class:
例如,这可能是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;
}
}
Ok, please note the Utils.toMap
: it's a function that allows you to convert a sequence of String, Object
into a Map
. 好的,请注意
Utils.toMap
:这是一个允许您将String, Object
序列转换为Map
的函数。 Ok, now Utils
is an example of a utility class (stupid, useless but a utility class nonetheless). 好的,现在
Utils
是实用程序类的一个示例(愚蠢,无用但仍然是实用程序类)。 In the spirit of OSGi I want to make this utility class a bundle as well : my thought would be to start this Utils bundle at framework boot and then whenever I need one of its utility I want to fetch a reference via
@Reference
annotation. 本着OSGi的精神,我也希望使该实用程序类成为捆绑软件 :我的想法是在框架启动时启动此Utils捆绑软件,然后每当我需要其实用工具之一时,我都希望通过
@Reference
批注获取引用。
This can work greatly in any bundle interface implementation, like this: 可以在任何bundle接口实现中很好地工作,如下所示:
@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
}
}
But what about other classes (ie called by BundleExampleImpl during its work)? 但是其他类(例如BundleExampleImpl在其工作期间调用)又如何呢? For example what about the
BundleExampleEvent
? 例如,
BundleExampleEvent
怎么BundleExampleEvent
? I need to call it from sayHello
method and I want to use this utility also inside that class in order to compute the Map! 我需要从
sayHello
方法调用它,并且我想在该类中也使用此实用程序来计算Map! In the previous example i used a static function, but I would like to use the reference of Utils
OSGi gave me. 在前面的示例中,我使用了静态函数,但是我想使用
Utils
OSGi给我的引用。
Of course I could add a parameter inside the constructor of
BundleExampleEvent
in order to satisfy the link but I rather not to do it because it's pretty silly that something would depend on an "utility class"; 当然,我可以在
BundleExampleEvent
的构造函数中添加一个参数以满足链接的要求,但我不想这样做,因为有些东西依赖于“实用程序类”,这很愚蠢。 my question are: 我的问题是:
Or can I do something weird like adding a reference of Utils also in my BundleExampleEvent
; 或者我可以做一些奇怪的事情,比如在
BundleExampleEvent
添加Utils的引用; ie something like this: 即这样的事情:
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; } }
Or maybe the whole idea of having an "utility bundle" is just pure trash? 也许拥有“公用事业捆绑包”的整个想法只是纯粹的垃圾?
Thanks for any reply. 感谢您的任何答复。 Hope I could convey my problem in the clearest way
希望我能以最清晰的方式传达我的问题
I don't think there is any point in Utils being a service. 我认为Utils作为服务没有任何意义。 Things should only be a service if they can conceivably have multiple implementations.
如果事物可以想象有多个实现,那么它们应该仅是一种服务。 In your case, the consumer of the Util functionality only ever wants a single implementation... the implementation is the contract.
在您的情况下,Util功能的使用者只需要一个实现...实现就是合同。
I don't even think the utils code should be in a bundle. 我什至不认为utils代码应该捆绑在一起。 Just make it into a library that is statically linked into the bundles that need it.
只需将其放入静态链接到需要它的包的库中即可。
In your case the Utils utils would be an OSGi service. 在您的情况下,Utils utils将是OSGi服务。 Then you want to use this service inside an object that is not a service like BundleExampleEvent.
然后,您想在不是BundleExampleEvent之类的服务的对象内部使用此服务。
What you could do is to create a service that creates BundleExampleEvent instances and feeds it with an OSGi service. 您可以做的是创建一个服务,该服务创建BundleExampleEvent实例并将其提供给OSGi服务。 Kind of like a factory as a service.
有点像工厂服务。 The problem with this is that services in OSGi are dynamic.
问题在于OSGi中的服务是动态的。 If the service needed by the BundleExampleEvent instance goes away then the object would have to be discarded.
如果BundleExampleEvent实例所需的服务消失,则必须丢弃该对象。 So this only works for short lived objects.
因此,这仅适用于短暂的对象。
In the eventadmin example a different solution would be to not use a special event class but instead create a service that has a method to send such an event. 在eventadmin示例中,另一种解决方案是不使用特殊事件类,而是创建一个具有发送此类事件的方法的服务。 Then all the magic would happen inside this method and the result would be an event without further logic.
然后,所有魔术将在此方法内发生,结果将是没有进一步逻辑的事件。 You could also inject EventAdmin into that service using DS.
您也可以使用DS将EventAdmin注入该服务。 This works very well in OSGI but has the disadvantage of the anemic domain model ( http://www.martinfowler.com/bliki/AnemicDomainModel.html ).
这在OSGI中效果很好,但缺点是贫血域模型( http://www.martinfowler.com/bliki/AnemicDomainModel.html )。
I am not sure which variant to prefer. 我不确定要选择哪种变体。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.