0

私は現在、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 フレームワークに登録される前に両方とも呼び出されるため、なぜそれらを分離する必要があるのでしょうか? 私の理解が間違っている場合は教えてください。

よろしくお願いします、

ジェイ

4

1 に答える 1

0

initメソッドとメソッドを両方持つ理由startは次のとおりです。依存関係マネージャーを使用すると、(Java) コードでコンポーネントとその依存関係を宣言的に定義できます。これはバンドルを開始するときに行うことができますが、コンポーネントには、一部の構成またはその他の依存関係の 1 つに依存する依存関係がある場合があります。つまり、実行時にコンポーネントに追加したい依存関係がある場合があります。

そのような場合にできることは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 に答える