0

I am now researching on the Opendaylight project (an open-source SDN controller project leaded by Cisco), and discovered that the project uses resources from apache.felix.dm package to dynamically manage the service dependencies on equinox (an OSGi framework) during runtime.

To understand the mechanism of dm, I have traced the code in ComponentImpl.java under apache.felix.dm package. What I understand now is:

  1. DependencyManager will invoke init() method after all the service dependencies are satisfied.
  2. the start() method will be invoked after init() method but before the services provided by the class are being registered on OSGi framework.

The invoking mechanism written in code is provided as follow (they are both located in ComponentImpl.java):

The method to invoke 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();
}

The method to invoke 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();
}

Now my question is: what's the difference between init() and start() method? Since they are both invoked before the service being registered on OSGi framework, why they needed to be seperated? Thx for any ideas, and please tell me if any of my understanding is incorrect.

Best Regards,

Jay

4

1 回答 1

0

同时具有 aninitstart方法的原因如下。依赖项管理器允许您在(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方法。

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

于 2013-11-12T12:39:27.270 回答