この小さな記事では、このライブラリを作成した理由を説明します。そしてそれはどのように実装されていますか?
私は多くのプロジェクトで Java EE フレームワークを使用しました。そのほとんどでは、アプリケーションを実行するために使用できるリソースに制限はありませんでしたが、まれにリソース、特にデプロイメント サービスにアプリケーションをデプロイするためのメモリに制限がある場合がありました。したがって、アプリケーションが制限を超えると、展開サービスは最初にアプリケーションの速度を低下させ、その後継続する場合はサービスによってシャットダウンされます。私たちはスプリング ブートもせずにレガシー Spring フレームワークを使用していました。別のライブラリを使用しようとしましたが、違いは最小限で価値がありませんでした。ここから、メモリ消費量をできる限り削減することに重点を置いた軽量の Spring 代替フレームワークを作成するというアイデアが始まりました。 .
ライブラリの設計を始めたとき、私の頭の中にあった目標は 2 つだけでした:
1 - メモリ消費を可能な限り削減します
2 - 学習の観点および移行自体の複雑さからライブラリへの移行を容易にするために、可能な限り既存の Java EE API を使用するようにしてください。
これら 2 つの目標により、アプリケーションの 1 つのメモリ フットプリントを約 40% 削減することができ、既存のソリューションと似ているため、移行を簡単かつ迅速に行うことができました。
ここに GitHub リポジトリがあるので、読みながらコードを確認できます。
ライブラリ全体には多くの部分 (下のスクリーンショット) があり、実装のほとんどはメイン モジュールにあり、コア、JPA、Web の 3 種類の独立したモジュールにも分割されています。 App モジュールは主に統合用であり、Plugin モジュールは、ライブラリが適切に動作するために必要なファイルをパッケージ アーカイブ内に作成するのに役立つ Maven プラグインです
それでは、名前が示すように、依存関係の注入または制御の反転であるライブラリのコア機能が含まれるコア モジュールから始めます。
この機能を実現するには、まずコンパイル段階で、ライブラリが管理するすべてのアノテーション付きクラスのアプリケーションのクラスパスをスキャンして、アノテーション付きクラスのコンポーネント定義を作成します。
コンポーネント定義には、基本的に、後でこのクラスからオブジェクトをインスタンス化するために必要なすべての情報が含まれています。たとえば、クラスに注入アノテーションを持つセッターがある場合 (コンストラクターとセッターの注入のみがサポートされます)、コンストラクター情報などです。インターフェイスを使用するか、他のクラスを拡張すると、このクラスからオブジェクトを作成するために必要な情報がすべて揃います (下のスクリーンショット)。
そして、すべてのクラスパスのアノテーションをスキャンし、必要なすべてのコンポーネント定義を作成した後、それらを JSON ファイルとしてクラスパスに保存します。
コア モジュールの 2 番目の主な機能は、ファクトリ設計パターンに基づく依存関係の注入と制御の反転です。そのため、ComponentFactoryApplicationContext インターフェイスがあります。 > インターフェイスであり、このインターフェイスのメイン メソッドは、コンポーネントの名前からオブジェクトを返す getComponent メソッドです。
上のスクリーンショットでわかるように、最初に、既に初期化されたシングルトン コンポーネントにコンポーネントが存在するかどうかを確認しようとします。存在しない場合は、JSON ファイルからコンポーネント定義を取得してから、while ループを開始して、コンポーネント定義とその依存関係をコンポーネント アセンブラに渡して、注入できる完全なオブジェクトを取得する前に、コンポーネントのすべての依存関係を取得します。
JPA モジュールの実装は Spring Data JPA に非常に似ていますが、非常に最小限です。これが非常に似ている理由は、私が多くのプロジェクトで Spring データを使用しており、使いやすいことがわかったためです。また、前に述べたように、ライブラリをスムーズに動作させ、必要な作業をできる限り少なくするため、独自のミニ Spring データ バージョンを実装することが最良の選択でした。
実装は、保存、削除、findAll などのデータベースの最も一般的な操作を含む JpaRepository インターフェースを中心に行われます。JPA モジュールを使用するには、このインターフェースを拡張し、このインターフェースが管理するエンティティを提供する必要があります。これは ID であり、インターフェイスを拡張してリポジトリ アノテーションでアノテーションを付けた後、メソッドを定義してクエリ アノテーションでアノテーションを付け、JPQL クエリを提供すると、コンパイル フェーズでライブラリがこのインターフェイスを実装する完全に機能するクラスを作成します。
ライブラリはアプリケーションのトランザクション部分も管理するため、すべてのリポジトリ インターフェイスとトランザクションのアノテーションが付けられたクラスは、トランザクションの観点からライブラリによって管理されます。そのため、トランザクション コンポーネントの場合、ライブラリは Transactional アノテーションに基づいてトランザクションを管理するプロキシを作成し、エンティティ マネージャーのライフサイクルも管理します。
Web モデルは、アプリケーションのすべての Web パーツの管理を担当します。設計上、これは独立したモジュールです。つまり、ライブラリ内の残りのモジュールから独立して使用できます。通常のように、使用方法はいくつかのモジュールと非常に似ています。 Spring Web や Jax-rs などの使い慣れた Java EE ライブラリ
実装はアノテーションに基づいており、Controller アノテーションが付けられたクラスがあり、このコントローラー内には PathMapping アノテーションが付けられたメソッドがあり、これらのメソッドは特定のパスまたは特定のメソッドを処理します。リクエストのタイプ、コンテンツ タイプなどの基準に基づいてリクエストを送信します。
外側から見ると、他のライブラリと非常によく似ていますが、内側から見ると異なります。ライブラリは実行時にこれらの Controller クラスを変更して、すべてのクラスが BaseHttpServlet を拡張するようにするためです。 も HttpServlet を拡張しており、通常のサーブレットとして機能します。
上のスクリーンショットでわかるように、まず init メソッドでコンポーネントを初期化し、WebApplicationContext を使用してすべての依存関係を注入します。その後、すべてのリクエストを処理します。 handleRequest メソッドを使用してこのコントローラーにアクセスします。このアプローチでは、既存のサーブレット API を使用してコントローラーを管理します。これにより、ライブラリーがプラグインとして機能するため、メモリーのフットプリントが低く抑えられ、オーバーヘッドも削減されます。サーブレット API の動作を補完します。
まず、リクエストを適切なメソッドにマッピングしようとします。その後、コンテキストまたはリクエストのような HttpServletRequest から情報を取得して、リクエストされたすべての情報をメソッド内に挿入しようとします。パラメータ、ヘッダー、パス変数、リクエストの本文...
これらの情報をすべて変換し、リクエストされたときにメソッドにパラメータとして挿入し、メソッドを実行して結果を PathMapping の生成またはコンテンツ タイプに基づいて変換します (デフォルトでは application/Json)、コンテンツを HttpServletResponse.
に書き込みます。最後に、プロセスで何か問題が発生してエラーがスローされた場合、このエラーまたは例外をキャッチし、例外のタイプに基づいて処理しようとします。さまざまなタイプの例外を処理する例外ハンドラーがあり、ユーザーは、希望する方法で例外を処理するために、より多くのハンドラーを提供することもできます。
最後の重要な部分は、アプリケーションが適切に動作し、jar または war パッケージをビルドするために必要なすべてのファイルを作成する Maven プラグインです。
まず、プラグインはクラスパスと依存関係をスキャンして component-settings-json ファイルを検索し、このファイルから次のものを生成します:
lazy-application.json: アプリケーションのすべてのコンポーネントとその依存関係が含まれます
lazy-application.properties: コントローラーとエンティティのリストが含まれているため、実行時にクラスパスをスキャンする必要はありません。
最後に、パッケージングが jar の場合、メインクラスを取得します。
そして最後に、アプリケーション コードとその依存関係、および前のステップで生成したファイルを含むパッケージ アーカイブ ファイルを構築します。
記事を短くし、理解しにくくするために、詳細には立ち入らないようにしました。もちろん、コードは GitHub で入手できるので、それを使って遊ぶこともできます。質問がある場合は、下にドロップしてください。試してみます。答えてください。
以上が軽量のミニスプリングの代替品を作成した理由とその方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。