需要在osgi包之间创建插件

时间:2016-05-11 10:21:41

标签: plugins osgi

我在我的应用程序中创建了一些包。 我想像这样插入这些包: enter image description here

我只想插入并插入这些捆绑包,因为我想要特定的fl / reason。

1 个答案:

答案 0 :(得分:1)

听起来你正在寻找一个插件模型并选择了OSGi而没有阅读如何做到这一点?

如果要在OSGi中创建插件模型,则使用 services 。服务在捆绑包之间定义合同。因此,在这种情况下,您的Core Bundle有许多地方可以让您的业务逻辑“插件”。对于每个这些地方,您需要定义服务合同。服务契约由Java包定义,通常需要一个或多个接口。

现在,在您的Core Bundle中,您将拥有组件。这些组件在OSGi中执行实际工作。要在组件中使用插件,组件依赖于插件服务。

因此,假设您有一个需要知道产品价格的组件,但该价格可能来自eBay,Amazon或Ali Baba。所以我们首先设计服务合同:

public interface SupplierPlugin {
    Set<Product> findProducts( String query ) throws Exception;
    boolean buy( String id, String count) throws Exception;
    String getSupplierId() throws Exception;
}

public class Product extends DTO {
    public String     supplier;
    public String     id;
    public String     name;
    public String     description;
    public Price      price;
    public int        inStock;
    public Duration   deliveryTime;
}

那么这在组件中看起来如何?

@Component
public class OrderProduct implements REST {

     @Reference
     volatile List<SupplierPlugin> suppliers;

     public Product findProducts(String query) {
         Product cheapest=null;

         return suppliers.stream()
             .flatMap( supplier -> supplier.findProducts(query) )
             .sorted( (a,b) -> a.price.compareTo(b.price) )
             .first();
     }

     public boolean buy(String supplier, String productId)  {        
         return suppliers.stream()
             .filter( supplier -> 
                  supplier.getSupplierId().equals(supplier) )
             .map( supplier -> supplier.buy( productId ) )
             .findFirst();
     }
 }

那么您将如何实施SupplierPlugin?

@Component
public class TestSupplier implements SupplierPlugin {

     @Reference
     DTOs dtos;

     static Product[] products = {

     };

     @Activate
     void activate() {
         InputStream in = TestSupplier.class
             .getResourceAsInputStream("products.json");
         products = dtos.decoder(Product[].class).get( 
     }

     public Set<Product> findProducts( String query ) {
        return Streams.of(products)
            .filter( product -> product.description.contains(query) )
            .collect( Collectors.toSet() );
     }
}

因此,您的术语与在OSGi中编写插件的实际方式之间的关键差异实际上是Bundles或多或少不可见的简单事实。设计100%围绕服务。

我已经接受了这个问题,并创建了一个小应用程序来演示这些概念。您可以在OSGi enRoute Examples repository

上找到它