简体   繁体   English

创建osgi实用程序包的用处

[英]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: 我的问题是:

  1. Is this the only method available if I want a "utility bundle"? 如果我需要“实用程序捆绑包”,这是唯一可用的方法吗?
  2. 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; } } 
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM