创建 osgi 实用程序包有多有用
how useful is to create an osgi utility bundle
我正在尝试使用 OSGi 框架开发一个简单的应用程序。我的问题涉及框架中可用的 "utility bundle" :让我用一个非常详细的例子来解释。目前我正在尝试构建我的捆绑包将发送的事件。
据我了解,我需要做的是像下面这样的事情(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 应用程序可能有很多包,我想为每个包创建一个事件的子class(例如,我有一个名为 "BundleExample" 的包?在它里面导出classes 会有一个 "BundleExampleEvent")。我 知道这不会添加任何信息,因为您可以通过查看 "topic" 知道您收到了哪个事件,但请暂时耐心等待 。
现在,Event
构造函数需要一个主题和一个 Map<String, Object>
。但是,对于 "simplify" 事件构造函数,我只想将主题和参数列表放入地图中。例如,这里可能是 BundleExampleEvent class:
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
是实用程序 class 的示例(愚蠢、无用但仍然是实用程序 class)。 本着 OSGi 的精神,我想把这个实用程序 class 也打包成一个包:我的想法是在框架启动时启动这个 Utils 包,然后每当我需要一个包时它的实用程序我想通过 @Reference
注释获取参考。
这在任何 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
}
}
但是其他 classes(即在其工作期间由 BundleExampleImpl 调用)呢?例如 BundleExampleEvent
呢?我需要从 sayHello
方法中调用它,并且我还想在 class 中使用此实用程序来计算地图!在前面的示例中,我使用了静态函数,但我想使用 Utils
OSGi 给我的参考。
当然我可以在 BundleExampleEvent
的构造函数中添加一个参数以满足 link 但我宁愿不这样做,因为它是非常愚蠢的是,某些东西将取决于 "utility class";我的问题是:
- 如果我想要 "utility bundle",这是唯一可用的方法吗?
或者我可以做一些奇怪的事情,比如在我的 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;
}
}
或者拥有一个 "utility bundle" 的整个想法纯粹是垃圾?
感谢您的回复。希望我能用最清楚的方式表达我的问题
在您的情况下,Utils 实用程序将是一个 OSGi 服务。然后你想在一个不是像 BundleExampleEvent 这样的服务的对象中使用这个服务。
您可以做的是创建一个服务来创建 BundleExampleEvent 实例并为其提供 OSGi 服务。有点像工厂即服务。问题在于 OSGi 中的服务是动态的。如果 BundleExampleEvent 实例所需的服务消失,则必须丢弃该对象。所以这只适用于短暂的对象。
在 eventadmin 示例中,一个不同的解决方案是不使用特殊事件 class 而是创建一个具有发送此类事件的方法的服务。然后所有的魔法都会在这个方法中发生,结果将是一个没有进一步逻辑的事件。您还可以使用 DS 将 EventAdmin 注入该服务。
这在 OSGI 中工作得很好,但有贫血域模型的缺点 (http://www.martinfowler.com/bliki/AnemicDomainModel.html)。
我不确定更喜欢哪种变体。
我不认为 Utils 是一项服务有任何意义。只有当事物可以有多种实现时,它们才应该是一种服务。在您的情况下,Util 功能的使用者只需要一个实现...实现 是 合同。
我什至认为 utils 代码不应该放在一个包中。只需将它变成一个静态链接到需要它的包的库。
我正在尝试使用 OSGi 框架开发一个简单的应用程序。我的问题涉及框架中可用的 "utility bundle" :让我用一个非常详细的例子来解释。目前我正在尝试构建我的捆绑包将发送的事件。
据我了解,我需要做的是像下面这样的事情(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 应用程序可能有很多包,我想为每个包创建一个事件的子class(例如,我有一个名为 "BundleExample" 的包?在它里面导出classes 会有一个 "BundleExampleEvent")。我 知道这不会添加任何信息,因为您可以通过查看 "topic" 知道您收到了哪个事件,但请暂时耐心等待 。
现在,Event
构造函数需要一个主题和一个 Map<String, Object>
。但是,对于 "simplify" 事件构造函数,我只想将主题和参数列表放入地图中。例如,这里可能是 BundleExampleEvent class:
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
是实用程序 class 的示例(愚蠢、无用但仍然是实用程序 class)。 本着 OSGi 的精神,我想把这个实用程序 class 也打包成一个包:我的想法是在框架启动时启动这个 Utils 包,然后每当我需要一个包时它的实用程序我想通过 @Reference
注释获取参考。
这在任何 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
}
}
但是其他 classes(即在其工作期间由 BundleExampleImpl 调用)呢?例如 BundleExampleEvent
呢?我需要从 sayHello
方法中调用它,并且我还想在 class 中使用此实用程序来计算地图!在前面的示例中,我使用了静态函数,但我想使用 Utils
OSGi 给我的参考。
当然我可以在 BundleExampleEvent
的构造函数中添加一个参数以满足 link 但我宁愿不这样做,因为它是非常愚蠢的是,某些东西将取决于 "utility class";我的问题是:
- 如果我想要 "utility bundle",这是唯一可用的方法吗?
或者我可以做一些奇怪的事情,比如在我的
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; } }
或者拥有一个 "utility bundle" 的整个想法纯粹是垃圾?
感谢您的回复。希望我能用最清楚的方式表达我的问题
在您的情况下,Utils 实用程序将是一个 OSGi 服务。然后你想在一个不是像 BundleExampleEvent 这样的服务的对象中使用这个服务。
您可以做的是创建一个服务来创建 BundleExampleEvent 实例并为其提供 OSGi 服务。有点像工厂即服务。问题在于 OSGi 中的服务是动态的。如果 BundleExampleEvent 实例所需的服务消失,则必须丢弃该对象。所以这只适用于短暂的对象。
在 eventadmin 示例中,一个不同的解决方案是不使用特殊事件 class 而是创建一个具有发送此类事件的方法的服务。然后所有的魔法都会在这个方法中发生,结果将是一个没有进一步逻辑的事件。您还可以使用 DS 将 EventAdmin 注入该服务。 这在 OSGI 中工作得很好,但有贫血域模型的缺点 (http://www.martinfowler.com/bliki/AnemicDomainModel.html)。
我不确定更喜欢哪种变体。
我不认为 Utils 是一项服务有任何意义。只有当事物可以有多种实现时,它们才应该是一种服务。在您的情况下,Util 功能的使用者只需要一个实现...实现 是 合同。
我什至认为 utils 代码不应该放在一个包中。只需将它变成一个静态链接到需要它的包的库。