web-dev-qa-db-ja.com

Spring BootをOSGiで使用できますか?そうでない場合、OSGi Spring Bootを使用する計画はありますか?

Spring BootをOSGiで使用できますか?そうでない場合、OSGi Spring Boot(Apache FelixまたはEclipse Equinox)を計画していますか?私の意見では、クラウドアプリケーションはOSGiが提供するように高度にモジュール化され、更新可能でなければなりません。

20
user3646774

はい、OSGIコンテナで_Spring Boot_アプリを実行することは可能です。

まず、Spring Boot jarパッケージからOSGI bundleに切り替える必要があります。

Mavenを使用している場合は、_org.Apache.felix:maven-bundle-plugin_を使用できます。 _Spring Boot_依存関係jarは有効なOSGIバンドルではないため、bndツールを使用して有効なバンドルにするか、バンドル自体に埋め込むことができます。これは、_maven-bundle-plugin_構成、特に_<Embed-Dependency>_を使用して行うことができます。

ただし、どうにかして_Spring Boot_アプリでバンドルを開始する必要があります。アイデアは、BundleActivatorでSpring Bootを開始することです。

_@Import(AppConfig.class)
@SpringBootConfiguration
@EnableAutoConfiguration
public class SpringBootBundleActivator implements BundleActivator {

    ConfigurableApplicationContext appContext;

    @Override
    public void start(BundleContext bundleContext) {
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        appContext = SpringApplication.run(SpringBootBundleActivator.class);
    }

    @Override
    public void stop(BundleContext bundleContext) {
        SpringApplication.exit(appContext, () -> 0);
    }
}
_

また、Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());によってバンドルをロードするOSGIクラスローダーにコンテキストクラスローダーを設定する必要があります。 Springはコンテキストクラスローダーを使用するため、これが必要です。

これは私のデモリポジトリで実際に見ることができます: https://github.com/StasKolodyuk/osgi-spring-boot-demo

9
StasKolodyuk

個別の回答として投稿する価値があると思います(回答に対するすべてのコメントを全員が読むわけではありません)。

@StasKolodyukの優れたソリューションは、OSGI環境でSpring Bootアプリケーションを実行する方法を提供します。

ただし、制限があります。OSGIで実行するとパッケージスキャンがサポートされないため、Spring Bootのアノテーションによる自動マッピングは機能しません。

これが別のトリックです。コンポーネントを備えたSpring Bootアプリをコードから自動取得してOSGIで実行することができます(私はKarafでテストしました)。

機能例は https://github.com/dimmik/osgi-spring-boot-demo にあります

コツは、SpringApplicationインスタンスに適切なResourcePatternResolverを提供することです。

package by.kolodyuk.osgi.springboot;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.osgi.io.OsgiBundleResourcePatternResolver;

@SpringBootApplication
public class SpringBootBundleActivator implements BundleActivator {

    ConfigurableApplicationContext appContext;

    @Override
    public void start(BundleContext bundleContext) {
        // Set context classloader (main trick, to enable SpringBoot start at the first place)
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        // trick to enable scan: get osgi resource pattern resolver
        OsgiBundleResourcePatternResolver resourceResolver = new OsgiBundleResourcePatternResolver(bundleContext.getBundle());
        // and provide it to spring application
        appContext = new SpringApplication(resourceResolver, SpringBootBundleActivator.class).run();
    }

    @Override
    public void stop(BundleContext bundleContext) {
        SpringApplication.exit(appContext, () -> 0);
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringBootBundleActivator.class);
    }
}
7

1つの可能性は、OSGiをSpring Bootアプリケーションに組み込んで、フレームワークを通じてアプリケーションの一部にアクセスできるようにすることです。 OSGiをプログラムで開始する方法については、 https://stackoverflow.com/a/4673904/173101 を参照してください。

しかし、一般的には「OSGi-Support」のようなものはありません。 OSGiはすべてのJavaアプリケーションに統合できます。逆の場合も同様に、すべてのJavaコード(また、Spring-Bootアプリケーション)をOSGiバンドルにパッケージ化して、OSGiコンテナー内で起動できます(ただし、それほど多くはありません)まったく意味がありません)。

6
Tom Seidel

Spring BootをOSGiにデプロイする理由はたくさんありますが、主な理由はパフォーマンスです。特に、Spring Bootサービスが機能しているサービス(つまり、開始、結果を返す、終了)の場合の起動パフォーマンスです。 Spring Bootで現在ベータテスト中のアプリケーションは、Equinoxにデプロイされた約0.5秒で起動するのに対し、3.5秒で起動します。他の理由は、OSGiベースのアプリケーションまたはJava EEサーバーへの統合です。

つまり、パフォーマンス上の理由から、OSGiはOSGi実装としてFelixまたはEquinoxよりもOSGi実装として多分優先されるでしょう。

別の代替方法は、Spring Bootアプリケーションで使用されるSpringライブラリを(WSO2から)MSF4Jにラップすることです。これは多くの作業を必要とせず、メモリ使用量の1/10で10倍高速に起動できます。

6
Andrew Glynn

スプリングブート-典型的なスプリングブートアプリは、osgiにとって少し「脂肪」です... starter-webまたはjerseyを使用している場合、ポートはすべてのosgiによって共有されるため、何らかのポート決定スキームを追加する必要があります。サービス」は、osgiランタイムが存在するシステムです。

私がスプリングブートを回避することができない限り、それを回避できないことをお勧めする理由は、作成したスプリングブートファットjar/warがサブクラスローダーを起動するためです。これは、標準のosgiクラスローダーの問題(com.whatever.someobject.MyClassが異なるバンドルとクラスローダーで同じではないため、他のすべてにエクスポートする同じバンドルから「インポート」されないため、混乱する場合)を単純化しません。バンドル間サービス通信の要件がある場合。

Webリスナーを必要としない場合は「スプリングブートコア」に対処するためのガイドに従い、標準のインポートに含まれないオブジェクトを使用するすべてのバンドル間サービスインターフェース(core =など)を回避することをお勧めしますJava se class etc ..)。ライフサイクルのみに関心がありますか?

2
some random

いいえ、OSGiをサポートしていません。 Spring Bootは、すべての依存関係を持つパッケージ化されたアプリケーションとしてマイクロサービスを作成し、実行可能JARにパッケージ化されたサーブレットコンテナーを作成することを目的としています。

2
dunni

マイクロサービスパターンに固執せず、OSGIアプリをREST API。簡単に管理するREST通信

0
Pontus Jörgne