Spring Bootの中のspring-boot-loadモジュールを分析します。
はじめに
通常の状況では、classiloaderはjarの中の現在のディレクトリまたはファイルクラスの中の*.classファイルしか見つけられません。入れ子jarの中のリソースをロードするためには、以前は入れ子jarの中のクラスファイルとアプリケーションのクラスファイルを一つのjarに包装していました。そうすると、入れ子jarが存在しなくなります。しかし、アプリケーションがどれに依存しているのかがよく分かりません。他の多くのjarの中のクラスは内容が違っていますが、ファイル名は同じです。springbootのspring-boot-loaderは優雅にこの問題を解決するために誕生しました。
spring-boot-loaderモジュールは、Java-jar archive.jarを使用して、Jarに依存する入れ子を含むjarまたはwarファイルを実行することを許可します。これらの起動器の目的は、JarLauncher、WarLauncher and Propties Launcherなどの三つの種類の起動器を提供します。Jar_War_Launcherは、現在のjarのlibディレクトリ内の入れ子jarファイル内のリソースを検索するために固定されている。
二、spring-boot-loaderモジュールが提供するjarディレクトリ構造
Sprigbootでjarファイルフォーマットは以下の通り固定されています。構造(1)JarファイルにおけるMANIFEST.MFファイル格納部 構造(2)Spring-book-loader自体が必要とするclass置き場 構造(3)アプリケーション自体のファイル置き場 構造(4)アプリケーション依存jarは、libディレクトリに固定される。 それではspring-bootはどのようにこの構造に従って資源をロードしますか?まずパッケージ化時にspring-boot-maven-pluginプラグインを使って打ち付けられたjarファイルを書き換えます。META-INF/MANIFEST.MFの を設定します。は、Java-jar archive.jarが実行するとき、LauncherはJarLauncherの種類をロードして実行します。JarLauncherは主に適切なURLClassLoader加載器を構成することに関心を持っています。 三、spring-boot-maven-pluginプラグインの包装プロセスの分析
注:ここではなぜlibに入れるべきだったspring-book-loader.jarの中のclassをコピーするのかを考えます。
四、JarLauncher実行フロー分析
この流れを見てから、第三節に残した問題を分析します。フローチャートのように、まずAppclassloaderを使ってJarLauncher類をロードしてLaunchedURLClassLoader類を作成しました。LaunchedURLClassLoaderはspring-book-loader.jarカバンの中に属します。Appclassloaderは普通のキャリアではjarの中に読み込めません。ですから、spring-boot-loader.jarをlibディレクトリに置くと、Apple classloaderはLaunchedURLClassLoaderを見つけられなくなります。包装する時に
コピーは元々libに入れるべきだったspring-book-loader.jarの中のclassを構造にしました。
五、まとめ
spring-boot-loadモジュールは、カスタムjarパッケージ構造のカスタムキャリアを通じて、エレガントにネストされたjarリソースのロードを実現し、パッケージ化時にブートクラスと組織jar構造を再設定し、実行時にカスタムキャリアを設定することにより、ネストされたjarリソースローディングを実現します。
通常の状況では、classiloaderはjarの中の現在のディレクトリまたはファイルクラスの中の*.classファイルしか見つけられません。入れ子jarの中のリソースをロードするためには、以前は入れ子jarの中のクラスファイルとアプリケーションのクラスファイルを一つのjarに包装していました。そうすると、入れ子jarが存在しなくなります。しかし、アプリケーションがどれに依存しているのかがよく分かりません。他の多くのjarの中のクラスは内容が違っていますが、ファイル名は同じです。springbootのspring-boot-loaderは優雅にこの問題を解決するために誕生しました。
spring-boot-loaderモジュールは、Java-jar archive.jarを使用して、Jarに依存する入れ子を含むjarまたはwarファイルを実行することを許可します。これらの起動器の目的は、JarLauncher、WarLauncher and Propties Launcherなどの三つの種類の起動器を提供します。Jar_War_Launcherは、現在のjarのlibディレクトリ内の入れ子jarファイル内のリソースを検索するために固定されている。
二、spring-boot-loaderモジュールが提供するjarディレクトリ構造
Sprigbootでjarファイルフォーマットは以下の通り固定されています。
archive.jar
|
+-META-INF(1)
| +-MANIFEST.MF
+-org(2)
| +-springframework
| +-boot
| +-loader
| +-<spring boot loader classes>
+-com(3)
| +-mycompany
| + project
| +-YouClasses.class
+-lib(4)
+-dependency1.jar
+-dependency2.jar
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.mycompany.project.MyApplication
spring-boot-loaderのカバンの中のclassファイルを構造(2)にコピーして、アプリケーションに依存して(4)アプリケーションクラスにコピーして(3)にコピーします。注:ここではなぜlibに入れるべきだったspring-book-loader.jarの中のclassをコピーするのかを考えます。
四、JarLauncher実行フロー分析
この流れを見てから、第三節に残した問題を分析します。フローチャートのように、まずAppclassloaderを使ってJarLauncher類をロードしてLaunchedURLClassLoader類を作成しました。LaunchedURLClassLoaderはspring-book-loader.jarカバンの中に属します。Appclassloaderは普通のキャリアではjarの中に読み込めません。ですから、spring-boot-loader.jarをlibディレクトリに置くと、Apple classloaderはLaunchedURLClassLoaderを見つけられなくなります。包装する時に
コピーは元々libに入れるべきだったspring-book-loader.jarの中のclassを構造にしました。
五、まとめ
spring-boot-loadモジュールは、カスタムjarパッケージ構造のカスタムキャリアを通じて、エレガントにネストされたjarリソースのロードを実現し、パッケージ化時にブートクラスと組織jar構造を再設定し、実行時にカスタムキャリアを設定することにより、ネストされたjarリソースローディングを実現します。