web-dev-qa-db-ja.com

Springフレームワークは何をしますか?それを使うべきですか?なぜか、なぜそうでないのか?

そこで、Javaで新しいプロジェクトを開始し、Springの使用を検討しています。なぜ春を考えているのですか?多くの人から、Springを使うべきだと言われています。真剣に、私は人々に春が何であるか、または何が何であるかを正確に説明するように努めさせたときはいつでも、私に正直な答えを与えることは決してできません。私はSpringSourceサイトでイントロをチェックしましたが、イントロは非常に複雑であるか、またはチュートリアルに重点が置かれており、どのイントロを使用する必要があるのか​​、またはどのように私の生活を楽にするのかについての良いアイデアはありません。 「依存性注入」という言葉が使われることもありますが、これは私をさらに混乱させます。その言葉の意味についての理解が違うからです。

とにかく、これは私の背景と私のアプリについて少しです:

Javaでしばらくの間、バックエンドWeb開発を行っています。はい、大量のユニットテストを行っています。これを容易にするために、通常、メソッドの(少なくとも)2つのバージョンを作成します:インスタンス変数を使用するものと、メソッドに渡される変数のみを使用するものです。インスタンス変数を使用するものは、インスタンス変数を提供する他のものを呼び出します。単体テストの時間になると、Mockitoを使用してモックしますオブジェクトを起動してから、インスタンス変数を使用しないメソッドを呼び出します。これは、私が「依存性注入」と常に理解していたことです。

私のアプリは、CSの観点から見るとかなりシンプルです。小規模なプロジェクト、1〜2人の開発者。ほとんどのCRUDタイプの操作で、大量の検索がスローされます。基本的には、一連のRESTful Webサービスと、Webフロントエンド、そして最終的にはいくつかのモバイルクライアントです。フロントエンドをストレートHTML/CSS/JS/JQueryで実行することを考えているため、JSPを使用する予定はありません。 ORMとしてHibernateを使用し、Webサービスを実装するためにJerseyを使用します。

私はすでにコーディングを始めており、実際に買い物をして、誰かが投資したいかどうかを確認できるデモを入手したいと思っています。ですから、明らかに時間が重要です。 Springにはかなりの学習曲線があることを理解しています。加えて、通常はペストのように回避しようとする一連のXML構成全体を必要とするようです。しかし、それが私の人生をより簡単にし、(特に)開発とテストをより速くすることができるのであれば、弾丸をかじってSpringを学ぶつもりです。

だからお願い。私を教育してください。 Springを使用する必要がありますか?なぜか、なぜそうでないのか?

245
sangfroid

Springフレームワークは何をしますか?それを使うべきですか?なぜか、なぜそうでないのか?

Springは、さまざまなコンポーネントを「ワイヤリング」するのに役立つフレームワークです。多くのコンポーネントがあり、それらをさまざまな方法で組み合わせることにしたり、さまざまな設定や環境に応じて1つのコンポーネントを別のコンポーネントに簡単に交換したい場合に、これは最も役立ちます。

これが「依存性注入」であると私が常に理解してきたことです。

別の定義を提案します。

「これらの依存関係が常に注入されることを期待して、オブジェクトが必要なものを提供するために外部の力に依存するようにオブジェクトを設計します誰かに通常の仕事を始めるように依頼する前。」

それと比較してください:「各オブジェクトは、外に出て、起動時に必要なものすべてを見つける責任があります。」

全体のXML構成が必要なようです

まあ、XML(またはアノテーションベース)のほとんどは、Springに次のように伝えています。

  • 誰かが「HammerStore」を要求したときに、_example.HammerStore_のインスタンスを作成して返してほしい。ストアは1つだけでよいので、次回のためにインスタンスをキャッシュします。
  • 誰かが「SomeHammer」を要求したときに、自分に「HammerStore」を要求し、ストアのmakeHammer()メソッドの結果を返してほしい。この結果をキャッシュしない
  • 誰かが「SomeWrench」を要求したら、_example.WrenchImpl_のインスタンスを作成してください。構成設定gaugeAmountを使用して、インスタンスのsetWrenchSize()プロパティに配置してください。結果をキャッシュしません。
  • 誰かが「LocalPlumber」を要求したときに、_example.PlumberImpl_のインスタンスを作成してください。文字列「Pedro」をsetName()メソッドに入れ、「SomeHammer」をsetHammer()メソッドに入れ、「SomeWrench」をsetWrench()メソッドに入れます。結果を返し、配管工が1つだけ必要なため、後で使用できるように結果をキャッシュします。

このように、Springを使用すると、コンポーネントに接続し、コンポーネントにラベルを付け、それらのライフサイクル/キャッシュを制御し、構成に基づいて動作を変更できます。

[テスト]を容易にするために、私は通常、メソッドの(少なくとも)2つのバージョンを作成します。1つはインスタンス変数を使用し、もう1つはメソッドに渡される変数のみを使用します。

それは私にとって多くの利益のために多くのオーバーヘッドのように聞こえます。代わりに、インスタンス変数に protectedまたはパッケージの可視性 を指定し、ユニットテストを同じ_com.mycompany.whatever_パッケージ内に配置します。そうすれば、テスト中にいつでもインスタンス変数を検査して変更できます。

113
Darien

最初に、依存性注入とは何ですか?

シンプル。クラスがあり、プライベートフィールド(nullに設定)があり、そのフィールドの値を提供するパブリックセッターを宣言しています。つまり、クラス(フィールド)の依存関係は、外部クラス(セッター経由)によって注入されます。それでおしまい。魔法のようなものはありません。

2番目、SpringはXMLがなくても使用できます(またはほとんど使用できません)

Spring 3.0.5.GA以降を使用している場合は、JDK6 +の依存関係注入サポートを使用できます。つまり、@Componentおよび@Resourceアノテーションを使用して依存関係を結び付けることができます。

なぜSpringを使用するのですか?

すべてのクラスには重要な依存関係のセッターがあり、必要な動作を提供するためにお気に入りのモックフレームワークを使用してこれらを簡単にモックできるため、依存関係注入は非常に簡単なユニットテストを促進します。

それとは別に、Springは、JEE標準テクノロジーを簡単に使用できるようにする基本クラスとして機能する多くのテンプレートも提供します。たとえば、JdbcTemplateはJDBCでうまく機能し、JpaTemplateはJPAで優れた機能を果たし、JmsTemplateはJMSを非常に簡単にします。 RestTemplateは、その単純さの点で優れています。例えば:

RestTemplate restTemplate = new RestTemplate();
MyJaxbObject o = restTemplate.getForObject("https://secure.example.org/results/{param1}?param2={param2}",MyJaxbObject.class,"1","2");

これで完了です。パラメータが挿入され、MyJaxbObjectにJAXBアノテーションを提供する必要があるだけです。 Maven JAXBプラグインを使用してXSDから自動生成した場合は、まったく時間がかかりません。キャスティングは行われておらず、マーシャラーを宣言する必要もなかったことに注意してください。すべて完了です。

Springの素晴らしさを永遠に試してみることができますが、RESTful Webサービスを接続して、トランザクションをサポートする注入されたDAOからデータを汲み出そうとする単純なコードスパイクを試してみるのがおそらく最善です。

69
Gary Rowe

まず第一に、依存性注入の理解は根本的に間違っているわけではありませんが、ほとんどの人がこの用語を使用するときの意味とはかなり異なります。あなたが説明するのは、テスト可能性を達成するためのかなり奇妙で型破りな方法です。他の開発者はその種のコードにかなり戸惑うことになるので、それから離れることをお勧めします。

一般に理解されている(そしてSpringによって実装されている)依存性注入とは、クラスが持つ依存関係(JDBCデータソースなど)がクラス自体によってフェッチされるのではなく、インスタンスの作成時にコンテナーによって「注入」されることを意味します。したがって、Datasourceを使用するすべてのメソッドに2つのバージョンがあるわけではありません。代わりに、「実際の」データソースが注入される依存関係注入構成と、モックが注入される依存関係構成があります。または、コンストラクターまたはゲッターを介してインジェクションが発生した場合、テストコードは明示的にインジェクションを実行できます。

第2に、Springは依存関係の注入だけではありませんが、それがコア機能です。また、宣言型トランザクション、ジョブスケジューリング、認証、および必要になる可能性のあるその他の機能(本格的なMVC Webフレームワークを含む)も提供します。同じ機能を提供する他のフレームワークがありますが、Spring以外はJava EEのみがそれらを統合します。

29

なぜSpringを使いたいのかについては、 http://www.wrox.com/WileyCDA/Section/Why-Use-the-Spring-Framework-.id-130098.html で読むことができます。 =

要約すれば :

  • J2EEアプリケーションには、過剰な量の「配管」コードが含まれる傾向があります。多くのコードレビューでは、JNDIルックアップコード、オブジェクトの転送、JDBCリソースを取得および解放するためのtry/catchブロックなど、何も実行しないコードの高い割合が繰り返し明らかになっています。 。 。 。このような配管コードを作成して保守することは、アプリケーションのビジネスドメインに焦点を当てるべきリソースの大きな浪費を証明します。

  • 多くのJ2EEアプリケーションは、これが不適切な分散オブジェクトモデルを使用します。これは、過剰なコードとコードの重複の主な原因の1つです。また、多くの場合、概念的に間違っています。内部に分散したアプリケーションは、同じ場所に配置されたアプリケーションよりも複雑で、多くの場合、パフォーマンスがはるかに低くなります。もちろん、ビジネス要件が分散アーキテクチャを要求する場合は、分散アーキテクチャを実装し、発生するトレードオフを受け入れる必要があります(そして、Springはそのようなシナリオに役立つ機能を提供します)。しかし、やむを得ない理由がない限り、そうすべきではありません。

  • EJBコンポーネントモデルは過度に複雑です。 EJBは、J2EEアプリケーションにビジネスロジックを実装する際の複雑さを軽減する方法として考えられました。実際には、この目的に成功していません。

  • EJBが過度に使用されています。 EJBは基本的に、内部に分散されたトランザクションアプリケーション用に設計されました。重要なアプリケーションのほとんどすべてがトランザクションに対応していますが、基本的なコンポーネントモデルにディストリビューションを組み込むべきではありません。

  • 「J2EE設計パターン」の多くは、実際には設計パターンではなく、テクノロジーの制限に対する回避策です。配布の過剰使用、およびEJBなどの複雑なAPIの使用により、多くの疑わしい設計パターンが生成されました。これらを批判的に検討し、よりシンプルで生産性の高いアプローチを探すことが重要です。

  • J2EEアプリケーションの単体テストは困難です。 J2EE API、特にEJBコンポーネントモデルは、アジャイルの動きが始まる前に定義されました。したがって、それらの設計は、単体テストの容易さを考慮していません。 APIと暗黙のコントラクトの両方を介して、アプリケーションサーバーの外部でEJBおよび他の多くのJ2EE APIに基づいてアプリケーションをテストすることは驚くほど困難です。ただし、高いテストカバレッジを達成し、データベースへの接続が失われるなど、多くの障害シナリオを再現するには、アプリケーションサーバーの外部でのユニットテストが不可欠です。また、開発または保守プロセス中にテストを迅速に実行できるようにし、再展開を待つ非生産的な時間を最小限に抑えることも重要です。

  • 特定のJ2EEテクノロジーは単に失敗しています。ここでの主な違反者はエンティティBeanであり、生産性とオブジェクト指向への制約が破滅的であることはほとんど証明されていません。

19
Rudy

Springフレームワークは何をしますか?

春は今日と同じように、単純なフレームワークとして知られているだけでなく、完全なエコシステムです。

春のエコシステムでカバーされるトピック:

  • Spring Framework(例:Dependency Injection、AOP ...)

  • 春の雲

  • 春のデータ

  • 春のセキュリティ

  • 春のバッチ

  • 春の社交

エコシステムの全範囲については こちら を参照してください。プロジェクトをチェリーピックすることが可能であり、DIに Google Guice を使用できます。セキュリティ関連の処理を行うSpring Security。エコシステム全体を購入する必要はありません。

春のフレームワーク自体は主に今日をカバーしています

  • 依存性注入

  • Springの宣言型トランザクション管理を含むアスペクト指向プログラミング

  • Spring MVC WebアプリケーションとRESTful Webサービスフレームワーク

  • JDBC、JPA、JMSの基本的なサポート

ソース spring.io

一般に、Springはコードで実装されたパターンとプラクティスのコレクションであり、アプリケーション開発サイクルの改善またはスピードアップに役立つと言えます。

それ(コアフレームワーク)が最もよく知られているのは、依存性注入の分野での機能です。 Spring自体は、いわゆる制御コンテナの反転または短い IoCコンテナ またはさらに短いコンテナ(「春」は同義語として使用されることもあります)。

依存性注入とは何ですか?

依存性注入とは、オブジェクトが外部化されたメカニズムを介して他のオブジェクトへのすべての依存関係を受け取ることを意味します。

あなたが車を持っていると言います、典型的な方法、それは実装されています:

public class Car {

    Engine e;

    public Car() { 
        e = new Engine(); 
    }

}

車のオブジェクトはエンジンに依存しています。エンジンは車のメンバーとして実装されているため、たとえば、エンジンと交換することはできません。テストエンジン。

依存性注入が登場します:

public class Car {

    Engine e;

    public Car(Engine e) { 
        this.e = e; 
    }

}

その後、エンジンを切り替えることができます。上記の内容はコンストラクターインジェクションと呼ばれます。他のタイプもあります。 setter-injectionまたはmethod-injection。 Springはこれをどのように支援しますか? Springを使用すると、注入するコンポーネントに@Autowiredアノテーションを付け、注入されたオブジェクトの配線を自動的に行うことができます。注入するコンポーネント自体に依存関係がある可能性があります。注射剤-いわゆる-は@Componentでマークされています

public class Car {

    Engine e;

    @Autowired
    public Car(Engine e) { 
        this.e = e; 
    }

}

しかし、それは、Springが提供する多くの機能の1つにすぎません。

Springを使用する必要がありますか?なぜか、なぜそうでないのか?

Springはそれほど邪魔にならないため、Springの使用を検討する必要のある多くの支援を提供します。特に新しいプロジェクトの場合、 Spring Boot は非常に魅力的です。 start.spring.io は、使いやすいpoint'n'click-interfaceを使用して、開始するプロジェクトテンプレートを生成します。 curlを使用してテンプレートを取得することもできます。

curl start.spring.io

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

:: Spring Initializr ::  https://start.spring.io

This service generates quickstart projects that can be easily customized.
Possible customizations include a project's dependencies, Java version, and
build system or build structure. See below for further details.

The services uses a HAL based hypermedia format to expose a set of resources
to interact with. If you access this root resource requesting application/json
as media type the response will contain the following links:
+-----------------+-----------------------------------------+
| Rel             | Description                             |
+-----------------+-----------------------------------------+
| gradle-build    | Generate a Gradle build file            |
| gradle-project  | Generate a Gradle based project archive |
| maven-build     | Generate a Maven pom.xml                |
| maven-project * | Generate a Maven based project archive  |
+-----------------+-----------------------------------------+

...

一方、 spark または dropwizard のようなフレームワークは、Webアプリをすばやく作成するための良い出発点にもなります。

13
Thomas Junk

以前は、コアJava、サーブレット、JSP、htmlとxml、JDBC APIだけを使用して、シンプルで効率的で高速なアプリケーションとWebサービスを作成していました。それは十分良かった。 JUnitはテストに適したツールでした。私たちのコードが機能するのは簡単でした。

Hibernateは、SQLを簡素化し、Javaオブジェクトを使用してデータベーステーブルの真のマッピングを可能にし、階層関係をオブジェクト関係マッピングまたはORMに反映することを可能にします。私はそれを気に入っていました。特にResultSetをJavaオブジェクトまたはデータ型にマップする必要はありませんでした。

Strutsが登場して、Model View ControllerパターンをWebアプリに追加しました。

EJBは大きなオーバーヘッドであり、苦痛と注釈により、コードはチキンスクラッチのように見えましたが、今やSpringは私たちの無実の人々に湧きました。それは私にはやり過ぎのようです。

たとえば、単純なjdbc url、userをパッケージ化して、最初にjdbc.propertiesに渡し、次にhibernateプロパティに渡し、次にSpring Beanに3回目に渡します。

それだけでなく、必要な場所で接続を取得することを検討してください。以下は、純粋なJavaで示すように非常に簡単です。これは、Springですべての熱気を処理した後で実際に行っていることです。

Connection connection = DriverManager.getConnection(url, user, pass);

それ自体は、他の大きなメリットがなく、簡単かつ迅速に簡単なことを実行するための大きなラウンドアラウンドの繰り返しです。それは、とにかく大切に保管している小さな素敵なギフトの周りに、何トンものギフト紙を巻くようなものです。

別の例は、バッチ更新です。 Springを使用すると、JdbcTemplateを使用してバッチ更新を実行する前に、かなりの数のクラス、インターフェースが複雑になります。単純なjdbcを使用すると、次のようになります。

Statement statement = connection.createStatement();
statement.addBatch(sqlquery);
statement.executeBatch();

それよりも簡単または速くなることはできません。

このフレームワークはサポートしていません。ごめんなさい。地球上で何か必要なときに注射を望んでいるのは誰ですか?

13
Uma

これは、Javaで記述されたフレームワークであり、Webアプリケーションを機能させるために多くのものが含まれています(たとえば、国際化のサポート)。アプリケーションをレイヤーに構造化するための優れた方法も提供します。長い目で見れば、多くの時間を節約できます。

Springについて学ぶのに適した本は、次のとおりです。 Expert Spring MVC and Web Flow

4
Bernard