1. 序章

このチュートリアルでは、 mvn spring -boot:runコマンドを使用してSpring BootWebアプリケーションを起動することと、 java-jarコマンド。

ここで、Spring Boot repackageゴールの構成に既に精通していると仮定しましょう。 このトピックの詳細については、 SpringBootを使用したファットジャーアプリの作成をお読みください。

2. SpringBootMavenプラグイン

Spring Bootアプリケーションを作成する場合、 Spring Boot Mavenプラグインは、コードをビルド、テスト、およびパッケージ化するための推奨ツールです。

このプラグインには、次のような便利な機能が多数付属しています。

  • それは私たちのために正しい依存関係のバージョンを解決します
  • すべての依存関係(必要に応じて組み込みアプリケーションサーバーを含む)を単一の実行可能なfat jar / warにパッケージ化でき、次のことも実行できます。
    • クラスパス構成を管理して、 java-jarコマンドでその長い-cpオプションをスキップできるようにします
    • カスタムClassLoaderを実装して、パッケージ内にネストされたすべての外部jarライブラリを見つけてロードします
    • main()メソッドを自動的に見つけてマニフェストで構成するため、 java-jarコマンドでメインクラスを指定する必要はありません。

3. 分解された形式でMavenを使用してコードを実行する

Webアプリケーションで作業しているときは、 Spring BootMavenプラグインのもう1つの非常に興味深い機能を活用できます。組み込みアプリケーションサーバーにWebアプリケーションを自動的にデプロイする機能です。

プラグインにTomcatを使用してコードを実行することを通知するために必要な依存関係は1つだけです。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency>

これで、プロジェクトのルートフォルダーで mvn spring-boot:run コマンドを実行すると、プラグインはpom構成を読み取り、Webアプリケーションコンテナーが必要であることを理解します。

mvn spring-boot:run コマンドを実行すると、Apache Tomcatのダウンロードがトリガーされ、Tomcatの起動が初期化されます。

試してみよう:

$ mvn spring-boot:run
...
...
[INFO] --------------------< com.baeldung:spring-boot-ops >--------------------
[INFO] Building spring-boot-ops 0.0.1-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] >>> spring-boot-maven-plugin:2.1.3.RELEASE:run (default-cli) > test-compile @ spring-boot-ops >>>
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/9.0.16/tomcat-embed-core-9.0.16.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/9.0.16/tomcat-embed-core-9.0.16.pom (1.8 kB at 2.8 kB/s)
...
...
[INFO] --- spring-boot-maven-plugin:2.1.3.RELEASE:run (default-cli) @ spring-boot-ops ---
...
...
11:33:36.648 [main] INFO  o.a.catalina.core.StandardService - Starting service [Tomcat]
11:33:36.649 [main] INFO  o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.16]
...
...
11:33:36.952 [main] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
...
...
11:33:48.223 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
11:33:48.289 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
11:33:48.292 [main] INFO  org.baeldung.boot.Application - Started Application in 22.454 seconds (JVM running for 37.692)

ログに「StartedApplication」を含む行が表示されたら、アドレスhttp:// localhost:8080/のブラウザを介してWebアプリケーションをクエリする準備ができています。

4. スタンドアロンのパッケージ化されたアプリケーションとしてのコードの実行

開発フェーズを通過し、アプリケーションを本番環境に移行したい場合は、アプリケーションをパッケージ化する必要があります。

残念ながら、 jar パッケージを使用している場合、基本的なMavenパッケージの目標には外部依存関係は含まれていません。

これは、より大きなプロジェクトのライブラリとしてのみ使用できることを意味します。

この制限を回避するには、 jar / warをスタンドアロンアプリケーションとして実行するには、MavenSpringBootプラグインrepackageの目標を活用する必要があります。

4.1. 構成

通常、ビルドプラグインを構成するだけで済みます。

<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        ...
    </plugins>
</build>

ただし、サンプルプロジェクトには複数のメインクラスが含まれているため、プラグインを構成することにより、実行するクラスをJavaに指示する必要があります。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.baeldung.webjar.WebjarsdemoApplication</mainClass>
            </configuration>
        </execution>
    </executions>
</plugin>

または、start-classプロパティを設定します。

<properties>
    <start-class>com.baeldung.webjar.WebjarsdemoApplication</start-class>
</properties>

4.2. アプリケーションの実行

これで、2つの簡単なコマンドを使用してサンプルの戦争を実行できます。

$ mvn clean package spring-boot:repackage
$ java -jar target/spring-boot-ops.war

jarファイルの実行方法の詳細については、記事コマンドライン引数を使用したJARアプリケーションの実行を参照してください。

4.3. WARファイルの内部

上記のコマンドが完全なサーバーアプリケーションを実行する方法をよりよく理解するために、spring-boot-ops.warを調べることができます。

それを解凍して中を覗くと、通常の容疑者が見つかります。

  • META-INF 、自動生成された MANIFEST.MF
  • WEB-INF / classes 、コンパイルされたクラスが含まれています
  • WEB-INF / lib 、これは戦争の依存関係と埋め込まれたTomcatjarファイルを保持します

ただし、ファットパッケージ構成に固有のフォルダーがいくつかあるため、これだけではありません。

  •   WEB-INF / lib-provided 、組み込みの実行時に必要な外部ライブラリが含まれていますが、デプロイ時には必要ありません
  • org / springframework / boot / loader は、Spring Bootカスタムクラスローダーを保持します—このライブラリは、外部依存関係をロードし、実行時にアクセスできるようにする役割を果たします。

4.4. 戦争マニフェストの内部

前述のように、Maven Spring Bootプラグインはメインクラスを検出し、javaコマンドの実行に必要な構成を生成します。

結果のMANIFEST.MFには、いくつかの追加行があります。

Start-Class: com.baeldung.webjar.WebjarsdemoApplication
Main-Class: org.springframework.boot.loader.WarLauncher

特に、最後の1つは、使用するSpringBootクラスローダーランチャーを指定していることがわかります。

4.5. Jarファイルの内部

デフォルトのパッケージ戦略により、 Spring Boot Mavenプラグインを使用するかどうかに関係なく、warパッケージシナリオに大きな違いはありません。

プラグインの利点をよりよく理解するために、pom packages構成をjarに変更して、 mvn cleanpackageを再度実行してみてください。

これで、ファットjarが以前のwarファイルとは少し異なって編成されていることがわかります。

  • すべてのクラスとリソースフォルダは、 BOOT-INF /classesの下に配置されています。
  • BOOT-INF /libはすべての外部ライブラリを保持します

プラグインがないと、 lib フォルダーは存在せず、 BOOT-INF /classesのすべてのコンテンツがパッケージのルートに配置されます。

4.6. ジャーマニフェストの内部

また、MANIFEST。MFが変更され、次の追加行が追加されました。

Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 2.1.3.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher

Spring-Boot-ClassesSpring-Boot-Libは、クラスローダーがクラスと外部ライブラリを見つける場所を教えてくれるので特に興味深いものです。

5. 選び方

ツールを分析するとき、 これらのツールが作成される目的を考慮することが不可欠です。 開発を容易にしたいですか、それともスムーズな展開と移植性を確保したいですか? この選択によって最も影響を受けるフェーズを見てみましょう。

5.1. 発達

開発者として、私たちは多くの場合、コードをローカルで実行するための環境のセットアップに多くの時間を費やすことなく、コーディングにほとんどの時間を費やしています。 単純なアプリケーションでは、それは通常問題ではありません。 ただし、より複雑なプロジェクトの場合は、環境変数を設定し、サーバーを起動し、データベースにデータを入力する必要があります。

アプリケーションを実行するたびに適切な環境を構成することは、特に複数のサービスを同時に実行する必要がある場合は、非常に非現実的です

そこで、Mavenでコードを実行すると役立ちます。 コードベース全体がすでにローカルでチェックアウトされているため、pom構成とリソースファイルを活用できます。 環境変数を設定し、メモリ内データベースを生成し、正しいサーバーバージョンをダウンロードして、1つのコマンドでアプリケーションをデプロイすることもできます。

各モジュールが異なる変数とサーバーバージョンを必要とするマルチモジュールコードベースでも、Mavenプロファイルを介して適切な環境を簡単に実行できます。

5.2. 製造

本番環境に移行すればするほど、会話は安定性とセキュリティに移行します。 そのため、開発マシンで使用されているプロセスを、実際の顧客がいるサーバーに適用することはできません。

この段階でMavenを介してコードを実行することは、複数の理由から悪い習慣です。

  • まず、Mavenをインストールする必要があります
  • 次に、コードをコンパイルする必要があるという理由だけで、完全なJava Development Kit(JDK)が必要です。
  • 次に、コードベースをサーバーにコピーして、すべてのプロプライエタリコードをプレーンテキストのままにする必要があります
  • mvn コマンドは、ライフサイクルのすべてのフェーズを実行する必要があります(ソースの検索、コンパイル、および実行)
  • 前のポイントのおかげで、CPUも無駄になり、クラウドサーバーの場合はお金も無駄になります
  • Mavenは、それぞれがメモリを使用する複数のJavaプロセスを生成します(デフォルトでは、それぞれが親プロセスと同じメモリ量を使用します)
  • 最後に、展開するサーバーが複数ある場合は、上記のすべてがそれぞれで繰り返されます

これらは、アプリケーションをパッケージとして出荷することが本番環境にとってより実用的である理由のほんの一部です。

6. 結論

このチュートリアルでは、Mavenを使用したコードの実行と java-jarコマンドを使用したコードの実行の違いについて説明しました。 また、いくつかの実際的なケースシナリオの概要を実行しました。

この記事で使用されているソースコードは、GitHubから入手できます。