【问题标题】:Eclipse RCP 4 use bundle via declarative serviceEclipse RCP 4 通过声明式服务使用包
【发布时间】:2012-11-06 07:06:20
【问题描述】:

我已经编写了一个 OSGi 包以在我的 eclipse 4 rcp 应用程序中使用它。如果我添加依赖项,在我的激活器中注册这些服务并将其注入我的类中,该服务的使用工作正常。

在激活器中

IUserService service = new TestUserService();
context.registerService(IUserService.class.getName(), service, null);

在我的课堂上

@Inject
IUserService service;

service.getSth();

我读到通过声明式服务使用捆绑包应该是更好的方法。所以改变了我的实现。 我在我的包中创建了一个组件定义来提供我的服务:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="usermanagement.test">
   <implementation class="usermanagement.test.TestUserService"/>
   <service>
      <provide interface="usermanagement.IUserService"/>
   </service>
</scr:component>

然后我从我的激活器中删除了服务注册并创建了一个服务消费者类:

public class UserServiceConsumer {

    private IUserService service;

    public synchronized void setQuote(IUserService service) {
        this.service = service;
    }

    public synchronized void unsetQuote(IUserService service) {
        if (this.service == service) {
            this.service = null;
        }
    }

}

和另一个组件定义:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="UserServiceConsumer">
   <implementation class="services.UserServiceConsumer"/>
   <reference bind="setService" cardinality="1..1" interface="usermanagement.IUserService" name="IUserService" policy="static" unbind="unsetService"/>
</scr:component>

在这些修改之后,我的服务注入不再起作用。问题是注入的服务引用每次都是NULL。

有人知道为什么吗?我是不是忘记了什么?

非常感谢!

【问题讨论】:

    标签: osgi eclipse-rcp declarative-services


    【解决方案1】:

    我可以建议您可以做一些调试。

    1. 您的运行时中是否真的有 scr 实现? SCR(声明式服务的另一个名称)不包含在 Equinox 核心中,因此您需要包含它。大多数人都使用 Felix SCR 包 - 它会非常高兴地安装在 Equinox 之上。

    2. 由于声明式服务只使用服务,您可以一次更改一半的应用程序,以确定是服务消费还是注册不起作用。

    3. 您还可以使用 Equinox 控制台检查您的服务注册。使用 'ss' 来标识您的捆绑包,然后使用 'bundle [no]' 来查看注册和使用的服务。如果您使用的是 Felix SCR,还有 Equinox 控制台扩展,因此您可以使用“scr list”查看捆绑包尝试注册的所有服务(及其状态),并使用“scr info”查看特定服务的更多详细信息服务。

    【讨论】:

      【解决方案2】:

      我找到了解决办法。

      在我的服务清单文件中,我添加了以下行:

      Bundle-ActivationPolicy: lazy
      

      之后,我的应用程序中的 userServiceConsumer 和组件定义就不再需要了。

      在视图类中,我现在可以执行以下操作:

      public class MyPart {
      
          private IUserService uServ;
      
          @Inject
          public MyPart(IUserService uServ) {
              this.uServ = uServ;
              if (uServ != null)
                  System.out.println("UserService available");
              else
                  System.out.println("UserService == null");
          }
      

      通过 DI,我的服务被注入到视图的构造函数中。这对我有用!

      【讨论】:

        【解决方案3】:

        我认为声明式服务在您的 UI 类中不起作用,因为它不是由 SCR 而是由 Eclipse 创建的。 因此,您可以尝试保持与 @Inject 相同的 UI,仅更改提供服务的捆绑包以使用 DS。

        基本上我什至不会尝试更改 UI 方面。 @Inject 符号的开销比声明式服务要少得多。

        【讨论】:

        • 如何推断 OP 想要在 UI 类中使用服务?
        • 我使用 DI 通过在类的构造函数上使用 @Creatable 注释来创建我的类的实例。
        • @tkotsis 如果您使用 Eclipse RCP,则通常用于构建 GUI
        猜你喜欢
        • 1970-01-01
        • 2021-01-05
        • 2014-03-06
        • 2010-10-15
        • 2012-04-27
        • 2018-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多