【问题标题】:what's the difference between init() and start() method in apache.felix.dm package?apache.felix.dm 包中的 init() 和 start() 方法有什么区别?
【发布时间】:2013-11-01 03:08:18
【问题描述】:

我现在正在研究 Opendaylight 项目(一个由 Cisco 领导的开源 SDN 控制器项目),发现该项目使用 apache.felix.dm 包中的资源来动态管理对 equinox(一个 OSGi 框架)的服务依赖) 在运行时。

为了了解dm的机制,我追踪了apache.felix.dm包下的ComponentImpl.java中的代码。我现在理解的是:

  1. DependencyManager 将在所有服务依赖项都满足后调用 init() 方法。
  2. start() 方法将在 init() 方法之后但在类提供的服务在 OSGi 框架上注册之前调用。

代码编写的调用机制如下(均位于ComponentImpl.java中):

调用init()的方法:

private void activateService(State state) {
    String init;
    synchronized (this) {
        init = m_callbackInit;
    }
    // service activation logic, first we initialize the service instance itself
    // meaning it is created if necessary and the bundle context is set
    initService();
    // now is the time to configure the service, meaning all required
    // dependencies will be set and any callbacks called
    configureService(state);
    // flag that our instance has been created
    m_isInstantiated = true;
    // then we invoke the init callback so the service can further initialize
    // itself
    invoke(init);
    // see if any of this caused further state changes
    calculateStateChanges();
}

调用start()的方法:

private void bindService(State state) {
    String start;
    synchronized (this) {
        start = m_callbackStart;
    }

    // configure service with extra-dependencies which might have been added from init() method.
    configureServiceWithExtraDependencies(state);
    // inform the state listeners we're starting
    stateListenersStarting();
    // invoke the start callback, since we're now ready to be used
    invoke(start);
    // start tracking optional services
    startTrackingOptional(state);
    // register the service in the framework's service registry
    registerService();
    // inform the state listeners we've started
    stateListenersStarted();
}

现在我的问题是:init() 和 start() 方法有什么区别?既然它们都是在服务注册到 OSGi 框架之前被调用的,为什么需要将它们分开呢?感谢您的任何想法,如果我的任何理解不正确,请告诉我。

最好的问候,

【问题讨论】:

  • 按照init的概念将其加载到类中,在调用时准备好,start调用
  • 对不起,你能解释一下你提到的“电话”吗?是不是类似于“回调”的功能?

标签: java osgi apache-felix


【解决方案1】:

同时拥有initstart 方法的原因如下。依赖管理器允许您在 (Java) 代码中以声明方式定义组件及其依赖关系。这可以在您启动捆绑包时完成,但有时组件可能具有依赖于某些配置或其其他依赖项之一的依赖项。换句话说,您可能需要在运行时将依赖项添加到组件中。

在这种情况下,您可以做的是在您的组件实现中定义一个init(Component c) 方法。此方法将在您的组件被初始化并且其所有必需的依赖项已被注入(或调用它们的回调)后被调用。因此,此时您可以访问组件中的此类依赖项,并且您可以根据通过此类依赖项获得的信息决定动态添加另一个组件,如下所示:

public volatile OtherService s; // an injected service dependency

public void init(Component c) {
  if (s.needsSomeService()) {
    DependencyManager dm = c.getDependencyManager();
    c.add(dm.createServiceDependency()
      .setService(SomeService.class)
      .setInstanceBound(true)
      .setRequired(true));
  }
}

一旦SomeService 可用,start() 方法将被调用并且您的组件变得可用(这意味着如果它发布了一个服务,那将立即完成)。

简而言之:init 方法的存在允许您操作自己的组件定义并在运行时动态添加额外的依赖项。一旦 所有 依赖项可用,就会调用 start 方法。

在没有此类要求的简单场景中,使用任何一种方法进行初始化都可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    相关资源
    最近更新 更多