共有しましょうJavaベースのWebアプリケーションアーキテクチャ!
Javaを使用して実装されるWebアプリケーション用のさまざまなアーキテクチャが多数あります。この質問への回答は、長所と短所を備えたさまざまなWebアプリケーション設計のライブラリとして役立つ場合があります。答えは主観的であることを理解していますが、できる限り客観的になり、リストにある長所と短所を動機付けましょう。
アーキテクチャの説明には、好みの詳細レベルを使用してください。回答が価値あるものであるためには、少なくとも、説明するアーキテクチャで使用されている主要なテクノロジーとアイデアを説明する必要があります。最後になりましたが、whenアーキテクチャを使用する必要がありますか?
始めます...
Java EE、Java Persistence API、Servlet and JavaのようなSunのオープン標準に基づく3層アーキテクチャを使用します。 =サーバーページ。
レイヤー間で可能な通信フローは次のように表されます。
Persistence <-> Business <-> Presentation
たとえば、プレゼンテーション層は永続化操作を呼び出したり実行したりせず、常にビジネス層を介して実行します。このアーキテクチャは、高可用性Webアプリケーションの要求を満たすことを目的としています。
作成、読み取り、更新、削除( [〜#〜] crud [〜#〜] )永続化操作を実行します。この場合、( Java Persistence API )JPAを使用しており、現在 Hibernate を永続プロバイダーとして使用し、 its EntityManager を使用しています。
このレイヤーは複数のクラスに分割され、各クラスは特定のタイプのエンティティ(つまり、ショッピングカートに関連するエンティティは単一の永続クラスで処理される)を処理し、sed by one one only manager。
さらに、このレイヤーには JPAエンティティ も格納されます。これは、Account
、ShoppingCart
などのようなものです。
Webアプリケーション機能に関連付けられているすべてのロジックは、このレイヤーにあります。この機能は、クレジットカードを使用してオンラインで製品の支払いを希望する顧客の送金を開始する場合があります。同様に、新しいユーザーを作成したり、ユーザーを削除したり、Webベースのゲームでの戦闘の結果を計算したりすることもできます。
この層は複数のクラスに分割され、これらの各クラスには@Stateless
の注釈が付けられ、 Stateless Session Bean (SLSB)になります。各SLSBはmanagerと呼ばれ、たとえば、マネージャーはAccountManager
と呼ばれるように注釈が付けられたクラスになります。
AccountManager
はCRUD操作を実行する必要がある場合、永続層のクラスであるAccountManagerPersistence
のインスタンスに適切な呼び出しを行います。 AccountManager
の2つのメソッドの概略図は次のとおりです。
...
public void makeExpiredAccountsInactive() {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
// Calls persistence layer
List<Account> expiredAccounts = amp.getAllExpiredAccounts();
for(Account account : expiredAccounts) {
this.makeAccountInactive(account)
}
}
public void makeAccountInactive(Account account) {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
account.deactivate();
amp.storeUpdatedAccount(account); // Calls persistence layer
}
コンテナマネージャトランザクション を使用しているため、自分でトランザクションの境界を設定する必要はありません。基本的に内部で起こることは、SLSBメソッドに入るときにトランザクションを開始し、メソッドを終了する直前にコミット(またはロールバック)することです。これは設定よりも規約の例ですが、デフォルトのRequired以外はまだ必要ありません。
以下に、SunのJava EE 5チュートリアル)が、エンタープライズJavaBean(EJB)の 必須トランザクション属性 を説明する方法を示します。
クライアントがトランザクション内で実行され、エンタープライズBeanのメソッドを呼び出す場合、メソッドはクライアントのトランザクション内で実行されます。クライアントがトランザクションに関連付けられていない場合、コンテナはメソッドを実行する前に新しいトランザクションを開始します。
Required属性は、コンテナ管理のトランザクション境界で実行されるすべてのエンタープライズBeanメソッドの暗黙的なトランザクション属性です。通常、別のトランザクション属性をオーバーライドする必要がない限り、Required属性を設定しません。トランザクション属性は宣言的であるため、後で簡単に変更できます。
プレゼンテーション層は...プレゼンテーションを担当しています!ユーザーインターフェイスを担当し、HTMLページを構築し、GETおよびPOSTリクエストを介してユーザー入力を受け取ります。現在、古い Servlet 'を使用して、ユーザーに情報を表示します。 s + Java Server Pages( [〜#〜] jsp [〜#〜] )の組み合わせ。
レイヤーは、ビジネスレイヤーのmanagersのメソッドを呼び出して、ユーザーが要求した操作を実行し、Webページに表示する情報を受け取ります。ビジネスレイヤーから受け取った情報は、String
'sおよびint
egersなどのそれほど複雑でないタイプである場合もあれば、 JPAエンティティ である場合もあります。
@NamedQuery
アノテーションを使用して、よく使用されるクエリを名前付きクエリとして保存できます。私たちのアーキテクチャのように、永続クラスに永続に関連するものができるだけ多くある場合、これにより、JPAエンティティを含めるためのクエリが見つかる場所が広がります。永続化操作を概観することは難しく、したがって維持することは難しくなります。Account
とShoppingCart
は、本当にビジネスオブジェクトではありませんか?これらのクラスに触れて、JPAが処理方法を知っているエンティティに変換する必要があるため、この方法で行われます。fetch=FetchType.LAZY
を使用して)必要なときにデータベースからロードするように構成されたJPAエンティティから情報をロードできません。例外をトリガーします。これらの種類のフィールドを含むエンティティを返す前に、関連するゲッターを必ず呼び出す必要があります。別のオプションは、Java Persistence Query Language( [〜#〜] jpql [〜#〜] )を使用し、FETCH JOIN
を実行することです。ただし、これらのオプションは少し面倒です。わかりました(短い)を行います:
Spingトランザクションサポートを使用し、サービスレイヤーに入ってからトランザクションを開始し、DAO呼び出しまで伝播します。サービスレイヤーは、ビジネスモデルの知識が最も多く、DAOは比較的簡単なCRUD作業を行います。
パフォーマンス上の理由から、バックエンドのより複雑なクエリによって、より複雑なクエリの一部が処理されます。
このケースでSpringを使用する利点は、Spring Proxyクラスの背後にある国/言語依存のインスタンスを持つことができることです。セッションのユーザーに基づいて、電話をかけるときに正しい国/言語の実装が使用されます。
トランザクション管理はほぼ透過的であり、ランタイム例外でロールバックされます。可能な限り、未チェックの例外を使用します。以前はチェック例外を実行していましたが、Springの導入により、チェックされていない例外の利点がわかり、可能な場合にのみ例外を処理します。多くの定型的な「キャッチ/リスロー」や「スロー」を避けます。
申し訳ありませんが、あなたの投稿よりも短いです。これが面白いと思ってください...
理想Java現在のWeb開発技術に基づいています。
HTML + CSS + Ajax + JQuery
プレイフレームワーク
Pure Javaコードをできるだけ長く使用します。Webサービスの融合はここで行えます。
XMLTool(Googleコードで検索)、JSoup、Google GSon、XStream、JOOX(Googleコードで検索)
CRUD:JPAまたはSienaProjectまたはQueryDSL /複雑なクエリ:JOOQ、QueryDSL
これが私の5セントです
Android、Angular.JS WebClient、OAUTHv2
REST、ジャージー(JAX-RS)、ジャクソン(JSONの非シリアル化)、DTOオブジェクト(ビジネスロジックモデルとは異なる)
DIおよびイベント処理用のSpring。モデルオブジェクトのDDD風のアプローチ。実行時間の長いジョブは、ワーカーモジュールのSQSでオフロードされます。
エンティティを格納するためのSpring JDBCテンプレートを備えたリポジトリモデル。順序付きリストを使用した、リーダーボード用のRedis(JEDIS)。トークンストアのMemcache。
MySQL、Memcached、Redis
私たちのプロジェクトで従ったことは次のとおりです。
フロントエンドテクノロジー
[〜#〜] api [〜#〜]
ビジネスロジック
春のデータ
SPRINGデータMongoDB
データベース
サーバー(キャッシュ用)
まだ通常のStruts-Spring-Hibernateスタックを使用しています。
将来のアプリについては、Spring Web Flow + Spring MVC + HibernateまたはSpring + Hibernate + Web Services with Flex front endを検討しています。
アーキテクチャの明確な特徴はモジュール化です。データベースには3から最大30のテーブルで始まるいくつかのモジュールがあります。ほとんどのモジュールは、ビジネスプロジェクトとWebプロジェクトで構成されています。ビジネスプロジェクトはビジネスロジックと永続ロジックを保持し、Webはプレゼンテーションロジックを保持します。
論理レベルでは、ビジネス、永続性、プレゼンテーションの3つのレイヤーがあります。
依存関係:
プレゼンテーションはビジネスと永続性に依存します。
永続性はビジネスに依存します。
ビジネスは他のレイヤーに依存しません。
ほとんどのビジネスプロジェクトには3種類のインターフェイスがあります(注:GUIではなく、プログラマティックJavaインターフェイスレイヤー)です。
多くの場合、1は2を拡張します。この方法により、モジュールの実装を別のものに簡単に置き換えることができます。これにより、さまざまなクライアントに導入し、より簡単に統合できます。一部のクライアントは特定のモジュールのみを購入するため、既存の機能を統合する必要があります。インターフェイスと実装層が分離されているため、依存モジュールに影響を与えることなく、その特定のクライアントのアドホックモジュール実装を簡単に展開できます。また、Spring Frameworkを使用すると、さまざまな実装を簡単に挿入できます。
私たちのビジネス層はPOJOに基づいています。私が観察している傾向の1つは、これらのPOJOがDTOに似ていることです。 anaemic domain model に苦しんでいます。なぜこれが起こっているのかはよくわかりませんが、多くのモジュールの問題領域の単純さ、作業の大部分がCRUDである、または開発者がロジックを別の場所に配置することを好むためである可能性があります。
私が取り組んだもう1つのウェブアーキテクチャがあります:
1つの主要な要件は、アプリケーションがモバイル/その他のデバイスをサポートすることでした。また、アプリケーションは、技術の選択の変化に対して拡張可能または柔軟でなければなりません。
プレゼンテーション層:
モバイルWeb(HTML5/CSS3 /レスポンシブデザイン)
Spring REST Controllers(JAX-RSに変更可能)
ビジネスサービス層:
Spring @Service(ステートレスEJBに変更可能)
データアクセス層:
Spring @Repository(ステートレスEJBに変更可能)
リソース層:
Hibernate(JPA)エンティティ(任意のORMに変更可能)
このアーキテクチャに従う本に関する詳細情報を見つけることができます here 。
私見、私たちのほとんどは共通の分母を持っています。少なくともバックエンドには、何らかの形式のIOC/DIコンテナーと永続化フレームワークがあります。個人的には、このためにGuiceとMybatisを使用しています。違いは、ビュー/ UI /プレゼンテーションレイヤーの実装方法にあります。ここには2つの主要なオプションがあります(それ以上の場合もあります)。現在、コンポーネントベースのプレゼンテーション層を使用しています(ウィケットを使用)。 URLやコントローラーではなく、コンポーネントやイベントを使用するデスクトップ環境を完全に模倣しています。現在、このURLコントローラーの種類のアーキテクチャに移行する必要がある理由を探しています(それが、このページにたどり着いた方法です)。なぜRESTfulおよびステートレスアーキテクチャに関する誇大広告。
手短にこの質問に答えるには、Guice IOCコンテナの上にコンポーネント指向のフレームワークを使用してステートフルWebアプリケーションを作成し、Mybatisを使用してリレーショナルデータベースにデータを入れます。
少し異なります。ここでは、よりモジュラーJavaアーキテクチャです。
上記に加えて、すべてのサービスに共通の機能プロバイダーである共有ライブラリモジュールがあります。
異なるレイヤーを使用することで、完全なデカップリングと必要なモジュール性が実現します。また、Java EEとSpringのパワーを完全に利用することもできます。必要に応じて、たとえばフロントエンドでJSFを使用することを妨げるものは何もありません。
OPによるアーキテクチャの例と比較すると、これは3つではなく4つの主要な層を持っていると説明できると思いますが、ひねりはあります。
その厳格なマネージャーパターンを使用するプロジェクトに取り組んできました。歴史的に、私はすべてがきちんとした箱に収まる堅固な階層の巨大な支持者でした。私のキャリアが進むにつれて、多くの場合、それが強制されることがわかります。アプリケーション設計に対してより機敏な考え方を採用することは、より良い製品につながると信じています。私がこれが意味することは、目前の問題を解決するクラスのセットを作成することです。 「あれこれのマネージャーを作りましたか?」
私が取り組んでいる現在のプロジェクトは、Spring MVCとRestEasy JSON/Ajax呼び出しを組み合わせたWebアプリです。コントローラーに組み込まれたサーバー側には、データベースへの直接アクセス、EJBアクセス、およびSOAPベースのWebサービスコールのためのJPA/Hibernateを備えた実用的なファサードベースのデータ層があります。 JSONとしてシリアル化してクライアントに返すものを決定するカスタムのJavaコントローラーコード。
Unixデザイン哲学の「悪い方が良い」という考え方を採用する代わりに、統一されたパターンを作成しようとする時間はほとんどありません。線の外側に色を付けて、賢明な何かを構築する方が、多くの厳しい設計上の義務を順守するものを構築するよりもはるかに優れているからです。
Web Application Architecture のコンポーネントには以下が含まれます。
1:ブラウザー:クライアントインタラクション
HTML
JavaScript
Stylesheet
2:インターネット
3:Webサーバー
CSS
Image
Pages(Java render )
4:アプリケーションサーバー
App Webapp (Java interaction)
Others WebApps
5:データベースサーバー
Oracle, SQL, MySQL
6:データ