what's the difference between init() and start() method in apache.felix.dm package?

StackOverflow https://stackoverflow.com/questions/19720161

  •  02-07-2022
  •  | 
  •  

문제

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

도움이 되었습니까?

해결책

The reason for having both an init and start method is as follows. The dependency manager allows you to declaratively define components and their dependencies in (Java) code. This can be done when you start the bundle, but sometimes a component might have a dependency that depends on some configuration, or one of its other dependencies. In other words, you might have dependencies that you want to add to the component at runtime.

In such cases, what you can do is define an init(Component c) method on your component implementation. This method will be invoked after your component has been initialized and all its required dependencies have been injected (or their callbacks invoked). So at that point you have access to such dependencies in your component and you could decide, based on information obtained through such dependencies, to dynamically add yet another component, like this:

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));
  }
}

Once SomeService becomes available, the start() method will be invoked and your component becomes available (meaning if it publishes a service, that will be done now).

In short: the init method exists to allow you to manipulate your own component definition and add extra dependencies dynamically at runtime. The start method is then invoked once all dependencies are available.

In simple scenarios, where you have no such requirements, using either method to do your initialization is fine.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top