私が最近取り組んでいるいくつかの大規模なプロジェクトでは、どちらか (XML または注釈) を選択することがますます重要になっているようです。プロジェクトが成長するにつれて、一貫性は保守性にとって非常に重要です。
私の質問は次のとおりです。注釈ベースの構成に対する XML ベースの構成の利点は何ですか? XML ベースの構成に対する注釈ベースの構成の利点は何ですか?
私が最近取り組んでいるいくつかの大規模なプロジェクトでは、どちらか (XML または注釈) を選択することがますます重要になっているようです。プロジェクトが成長するにつれて、一貫性は保守性にとって非常に重要です。
私の質問は次のとおりです。注釈ベースの構成に対する XML ベースの構成の利点は何ですか? XML ベースの構成に対する注釈ベースの構成の利点は何ですか?
注釈には用途がありますが、XML 構成を無効にする唯一の特効薬ではありません。2つ混ぜるのがオススメ!
たとえば、Spring を使用している場合、アプリケーションの依存性注入部分に XML を使用することは完全に直感的です。これにより、コードの依存関係がそれを使用するコードから離れます。対照的に、依存関係を必要とするコードで何らかの注釈を使用すると、コードはこの自動構成を認識します。
ただし、トランザクション管理に XML を使用する代わりに、注釈を使用してメソッドをトランザクションとしてマークすることは完全に理にかなっています。これはプログラマーが知りたいと思う情報だからです。ただし、インターフェイスが SubtypeX ではなく SubtypeY として注入されることは、クラスに含めるべきではありません。なぜなら、今 SubtypeX を注入したい場合は、コードを変更する必要がありますが、以前はインターフェイス コントラクトがあったためです。 XML を使用すると、XML マッピングを変更するだけで済み、それを行うのは非常に迅速で簡単です。
私は JPA アノテーションを使用したことがないので、それらがどれほど優れているかはわかりませんが、Bean のデータベースへのマッピングを XML のままにしておくことも良いと主張します。 、その情報で何ができるかを気にする必要があります。しかし、JPA が好きなら (私は経験がありません)、ぜひ行ってみてください。
一般に、注釈が機能を提供し、それ自体がコメントとして機能し、この注釈なしで正常に機能するためにコードを特定のプロセスに結び付けない場合は、注釈を使用します。たとえば、トランザクションとしてマークされたトランザクション メソッドは、その操作ロジックを強制終了せず、適切なコード レベルのコメントとしても機能します。それ以外の場合、この情報はおそらく XML として表現するのが最適です。これは、最終的にコードの動作に影響を与えますが、コードの主な機能を変更しないため、ソース ファイルには含まれないためです。
ここには、外部化されたメタデータとインライン化されたメタデータの問題という、より広い問題があります。オブジェクトモデルが1つの方法でのみ永続化される場合は、インライン化されたメタデータ(つまり注釈)がよりコンパクトで読みやすくなります。
ただし、オブジェクトモデルがさまざまなアプリケーションで再利用され、各アプリケーションがさまざまな方法でモデルを永続化する必要がある場合は、メタデータ(つまり、XML記述子)を外部化することがより適切になります。
どちらも優れているわけではないため、注釈はよりファッショナブルですが、両方がサポートされています。その結果、JPAのような新しいヘアオンファイアフレームワークはそれらをより重視する傾向があります。どちらも十分ではないことがわかっているため、ネイティブHibernateのようなより成熟したAPIは両方を提供します。
私は常に、アノテーションをクラスの能力、またはクラスが他のクラスとどのように相互作用するかを示す何らかの指標と考えています。
一方、私にとってのSpring XML構成は、まさにその構成です。
たとえば、プロキシの IP とポートに関する情報は、確実に XML ファイルに入ります。これはランタイム構成です。
を使用して@Autowire
、@Element
フレームワークにクラスの処理方法を示すことは、注釈をうまく使用することです。
URL を@Webservice
アノテーションに入れるのはスタイルが悪いです。
しかし、これは私の意見です。インタラクションと構成の境界線は必ずしも明確ではありません。
私はSpringを数年使用していますが、必要なXMLの量は間違いなく退屈になりました。Spring 2.5の新しいXMLスキーマとアノテーションサポートの間で、私は通常次のことを行います。
「component-scan」を使用して、@ Repository、@ Service、または@Componentを使用するクラスを自動ロードします。私は通常、すべてのBeanに名前を付けてから、@Resourceを使用してそれらを相互に接続します。この配管はあまり頻繁に変更されないので、注釈は理にかなっています。
すべてのAOPに「aop」名前空間を使用します。これは本当にうまくいきます。@Transactionalをあちこちに配置するのは一種のドラッグなので、私はまだトランザクションにも使用しています。任意のサービスまたはリポジトリのメソッドに名前付きポイントカットを作成し、アドバイスを非常に迅速に適用できます。
LocalContainerEntityManagerFactoryBeanをHibernateJpaVendorAdapterと一緒に使用して、Hibernateを構成します。これにより、Hibernateはクラスパス上の@Entityクラスを簡単に自動検出できます。次に、LCEMFBを参照して「factory-bean」と「factory-method」を使用して、名前付きSessionFactoryBeanを作成します。
注釈のみのアプローチを使用する際の重要な部分は、「Bean 名」の概念が多かれ少なかれなくなる (重要でなくなる) ことです。
Spring の「Bean 名」は、実装クラスに対する追加レベルの抽象化を形成します。XML Bean は、その Bean 名に関連して定義および参照されます。アノテーションを使用すると、それらはクラス/インターフェースによって参照されます。(Bean名は存在しますが、知る必要はありません)
余分な抽象化を取り除くことで、システムが簡素化され、生産性が向上すると強く信じています。大規模なプロジェクトの場合、XML を取り除くことによるメリットはかなり大きいと思います。
可視性は、XML ベースのアプローチの大きな利点だと思います。XMLドキュメントをナビゲートするためのさまざまなツール(つまり、Visual Studio + ReSharperのファイル構造ウィンドウ)があることを考えると、XMLはそれほど悪くはありません。
確かに混合アプローチを取ることはできますが、プロジェクトの新しい開発者がさまざまなオブジェクトが構成またはマップされている場所を把握するのが難しくなる可能性があるという理由だけで、それは危険に思えます。
知らない; 結局のところ、XML Hell はそれほど悪いものではないように思えます。
注釈を使用して構成できないオプションがいくつかあるため、構成するすべてのものに依存します。注釈の側から見ると、次のようになります。
何が大事かはあなた次第…
一般に、1 つの方法を選択して、製品の閉じた部分全体に使用することをお勧めします...
(いくつかの例外を除いて: たとえば、XML ベースの構成を選択した場合、@Autowire アノテーションを使用しても問題ありません。混在していますが、これは読みやすさと保守性の両方に役立ちます)
リファクタリングやその他のコード変更など、比較する他の側面があります。XML を使用する場合、すべての XML コンテンツを処理する必要があるため、リファクタリングに多大な労力がかかります。しかし、アノテーションを使えば簡単です。
私の好みの方法は、アノテーションを使用しない (または最小限の) Java ベースの構成です。http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
私もミックスがベストだと思いますが、設定パラメータの種類にもよります。私はSpringも使用するSeamプロジェクトに取り組んでおり、通常は別の開発サーバーとテストサーバーにデプロイしています。だから私は分割しました:
主な違いは、すべてのサーバー固有の構成の変更に対してコードを再コンパイルする必要がなく、xml ファイルを編集するだけであるということです。関連するすべてのコードを理解していないチーム メンバーが一部の構成変更を行うことができるという利点もあります。
私は間違っているかもしれませんが、アノテーション (Java の @Tag や C# の [属性] など) はコンパイル時のオプションであり、XML は実行時のオプションであると考えていました。私にとっては、それらは同等ではなく、長所と短所が異なると言っています。
常に特定の Java コンポーネント (クラス、メソッド、またはフィールド) にリンクされる構成情報は、アノテーションで表現するのに適しています。この場合、構成がコードの目的の中核である場合、注釈は特にうまく機能します。アノテーションには制限があるため、各コンポーネントが 1 つの構成しか持てない場合も最適です。複数の構成、特に注釈を含む Java クラスの外部にあるものを条件とする構成を処理する必要がある場合、注釈は解決するよりも多くの問題を引き起こす可能性があります。最後に、注釈は Java ソース コードを再コンパイルしないと変更できないため、実行時に再構成可能にする必要があるものは注釈を使用できません。
以下のリンクを参照してください。それらも役立つかもしれません。
DI コンテナーの範囲では、アノテーション ベースの DI は Java アノテーションの使用を悪用していると考えます。そうは言っても、プロジェクトで広く使用することはお勧めしません。プロジェクトで DI コンテナーの機能が本当に必要な場合は、Spring IoC と Xml ベースの構成オプションを使用することをお勧めします。
単体テストのためだけの場合、開発者はコーディングに Dependency Inject パターンを適用し、EasyMock や JMock などのモック ツールを利用して依存関係を回避する必要があります。
間違ったコンテキストで DI コンテナーを使用しないようにする必要があります。
私の経験から、注釈構成にはいくつかの長所と短所があります。
私は両方のアプローチを組み合わせることを好みます-構成の地獄を最小限に抑えるJavaアノテーションと必須のxml最小値。
これは、古典的な「構成とコンベンション」の質問です。ほとんどの場合、個人の趣味が答えを決定します。ただし、個人的には、規約より規約(つまりXMLベース)の方が好きです。IMO IDEは、XMLベースのアプローチの構築と維持に関連することが多いXML地獄の一部を克服するのに十分な堅牢性を備えています。結局、構成の利点(XML構成ファイルを構築、保守、および展開するためのユーティリティの構築など)は、長期的には従来の方法よりも重要であることがわかりました。
Spring Framework の場合、@Component アノテーションを使用して "component-scan" オプションを設定し、Spring が Java Bean を見つけられるようにして、すべての Bean を XML で定義する必要がないようにするというアイデアが気に入っています。 JavaConfig. たとえば、(理想的にはインターフェースを介して) 他のクラスに接続する必要があるステートレスなシングルトン Java Bean の場合、このアプローチは非常にうまく機能します。一般に、Spring Bean については、ほとんどの場合、Bean を定義するために Spring XML DSL から離れており、構成のコンパイル時のチェックとリファクタリングのサポートが得られるため、JavaConfig と Spring Annotations の使用を好むようになりました。 Spring XML 構成で取得します。JavaConfig/Annotations が XML 構成を使用して利用できることを実行できないことがわかったまれなケースでは、2 つを混在させます。
Hibernate ORM (JPA はまだ使用していません) の場合、ドメイン モデル クラスの注釈は、私が過去数年間に採用した階層化アーキテクチャ スタイルであるクリーン アーキテクチャにある程度違反しているため、XML マッピング ファイルを好みます。違反が発生するのは、Core Layer が Hibernate や JPA ライブラリなどの永続性関連のものに依存する必要があり、ドメイン モデル POJO の永続性を無視することが少なくなるためです。実際、コア層は他のインフラストラクチャに依存することはまったく想定されていません。
ただし、The Clean Architecture があなたの「一杯」でない場合は、別の XML マッピング ファイルよりもドメイン モデル クラスで Hibernate/JPA アノテーションを使用する方が確実に利点 (利便性や保守性など) があることがわかります。
私は両方を使用します。ほとんどが XML ですが、共通のクラスから継承し、共通のプロパティを持つ多数の Bean がある場合、スーパークラスでそれらのアノテーションを使用するため、各 Bean に同じプロパティを設定する必要はありません。私は少しコントロールが苦手なので、オートワイヤリングの代わりに @Resource(name="referredBean") を使用します (元のreferredBean と同じクラスの別の Bean が必要になった場合でも、多くの問題を回避できます)。 .