この小さな記事では、このライブラリを作成した理由を説明してみます。そしてそれはどのように実装されていますか?
私は多くのプロジェクトで Java EE フレームワークを使用しました。そのほとんどでは、アプリケーションを実行するために使用できるリソースに制限はありませんでしたが、まれにリソース、特にデプロイメント サービスにアプリケーションをデプロイするためのメモリに制限がある場合がありました。したがって、アプリケーションが制限を超えると、展開サービスは最初にアプリケーションの速度を低下させ、その後継続する場合はサービスによってシャットダウンされます。私たちはスプリング ブートもせずにレガシー Spring フレームワークを使用していました。別のライブラリを使用しようとしましたが、違いは最小限で価値がありませんでした。ここから、メモリ消費量をできる限り削減することに重点を置いた軽量の Spring 代替フレームワークを作成するというアイデアが始まりました。 .
ライブラリの設計を始めたとき、私の頭の中にあった目標は 2 つだけでした :
1 - メモリ消費量を可能な限り削減する
2 - 学習の観点および移行自体の複雑さからライブラリへの移行を容易にするために、可能な限り既存の Java EE API を使用するようにしてください。
これら 2 つの目標により、アプリケーションの 1 つのメモリ フットプリントを約 40% 削減することができ、既存のソリューションと似ているため、移行を簡単かつ迅速に行うことができました。
ここに GitHub リポジトリがあるので、読みながらコードを確認できます。
ライブラリ全体には多くの部分 (以下のスクリーンショット) があり、実装のほとんどはメイン モジュールにあり、コア、JPA、Web の 3 種類の独立したモジュールにも分割されています。 App モジュールは主に統合用であり、Plugin モジュールは、ライブラリが適切に動作するために必要なファイルをパッケージ アーカイブ内に作成するのに役立つ Maven プラグインです
それでは、名前が示すように、依存関係の注入または制御の反転であるライブラリのコア機能が含まれるコア モジュールから始めます。
この機能を実現するには、まずコンパイル段階で、ライブラリが管理するすべてのアノテーション付きクラスのアプリケーションのクラスパスをスキャンして、アノテーション付きクラスのコンポーネント定義を作成します。
コンポーネント定義には、基本的に、後でこのクラスからオブジェクトをインスタンス化するために必要なすべての情報が含まれています。たとえば、クラスに注入アノテーションを持つセッターがある場合 (コンストラクターとセッターの注入のみがサポートされます)、コンストラクター情報などです。インターフェイスを使用するか、他のクラスを拡張すると、このクラスからオブジェクトを作成するために必要な情報がすべて揃います (下のスクリーンショット)。
そして、すべてのクラスパスのアノテーションをスキャンし、必要なすべてのコンポーネント定義を作成した後、それらを JSON ファイルとしてクラスパスに保存します。
コア モジュールの 2 番目の主要な機能は、ファクトリ設計パターンに基づく依存関係の挿入と制御の反転です。そのため、ComponentFactory を自己拡張する ApplicationContext インターフェイスがあります。 ] インターフェイスであり、このインターフェイスのメイン メソッドは、コンポーネントの名前からオブジェクトを返す 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-definitions-json ファイルを検索し、このファイルから次のものを生成します:
lazy-application.json: アプリケーションのすべてのコンポーネントとその依存関係が含まれています
lazy-application.properties: コントローラーとエンティティのリストが含まれるため、実行時にクラスパスをスキャンする必要はありません。
最後に、パッケージングが jar の場合、メインクラスを取得します。
そして最後に、アプリケーション コードとその依存関係、および前のステップで生成したファイルを含むパッケージ アーカイブ ファイルを構築します。
記事を短くし、理解するのがそれほど複雑にならないように、詳細には立ち入らないようにしました。もちろん、コードは GitHub で入手できるので、それを使って遊ぶこともできます。質問がある場合は、下にドロップしてください。試してみます。答えてください。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3