Springフレームワークは何をしますか?使用すべきですか?なぜですか?


237

そのため、私はJavaで新しいプロジェクトを開始し、Springの使用を検討しています。なぜ春を検討するのですか?多くの人が私にSpringを使うべきだと言っているからです!真剣に、私は人々にSpringが何であるか、それが何であるかを説明するように試みたときはいつでも、彼らは私にまっすぐな答えを与えることはできません。SpringSourceサイトでイントロを確認しましたが、それらは非常に複雑であるか、本当にチュートリアルに焦点を当てています。いずれも、私がそれを使用する理由、またはそれが私の生活を楽にする方法について良いアイデアを与えてくれません。時々、人々は「依存性注入」という用語をまき散らしますが、これは私をさらに混乱させるだけです。なぜなら、その用語の意味が違うと思うからです。

とにかく、私の背景とアプリについて少し説明します。

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

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

私はすでにコーディングを始めており、デモを手に入れたいと思っています。したがって、明らかに時間が重要です。Springには学習曲線がかなりあることを理解していますが、それに加えて、多くのXML構成が必要なように見えますが、通常はペストのように避けるようにしています。しかし、それが私の生活を楽にすることができ、そして(特に)それが開発とテストをより速くすることができるなら、私は弾丸を噛んで春を学ぼうと思っています。

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


10
あなたがそれを気に入って、あなたのプロジェクトに適しているかどうかを確かめるには、しばらく試してみる必要があると思います。個人的には嫌いです。
リチャード

1
XMLまたは注釈を使用できますが、Springは構成の考え方よりも慣習をとることに留意してください。それは必ずしもあなた対処しなければならないアイテムのチェックリストではありません。
アーロンマクアイバー

14
この質問がかなり広いことは事実ですが、未解決のままにしておくべきだと思います。「Springは中規模のプロジェクトにどのようなメリットをもたらしますか?」と読みましたが、これは良い質問です。
sleske

1
私のお気に入りの技術書、Craig WallsのSpring in Action、第3版を読むことを強くお勧めします。それは素晴らしい読み物であり、あなたのプログラム方法を変えるでしょう。
14年

4
エンタープライズJavaを考えると、Springでできないことを簡単に答えることができます
...-m3th0dman

回答:


108

Springフレームワークは何をしますか?使用すべきですか?なぜですか?

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

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

別の定義をお勧めします:

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

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

大量のXML設定が必要なようです

さて、XML(または注釈ベース)のほとんどは、次のようなSpringのものを伝えています。

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

このようにして、Springはコンポーネントの接続、ラベル付け、ライフサイクル/キャッシュの制御、構成に基づいた動作の変更を可能にします。

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

それは、私にとってはあまり利益にならないほどのオーバーヘッドのように聞こえます。代わりに、インスタンス変数にprotectedまたは可視性を持たせ、同じcom.mycompany.whateverパッケージ内の単体テストを見つけます。そうすれば、テスト中にいつでもインスタンス変数を検査および変更できます。


65

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

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

第二に、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の不思議について永遠にしている可能性がありますが、おそらく最善のことは、トランザクションをサポートする注入されたDAOからデータを送り出すRESTful Webサービスを接続しようとする単純なコードスパイクを試すことです。


4
ええ、RestTemplateはとても素晴らしいです。100行ほどのコードがあり、それを破棄して2〜3行に置き換えることができます。
ケビン

11
詳細:依存性注入には、コンストラクターベースのアプローチも含まれます。必ずしもセッターを持っている必要はありません。
ダリエン

28

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

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

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


OPはDIを完全に理解しています
バシレフ

19

なぜ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です。これは、生産性とオブジェクト指向に対する制約において、ほとんど壊滅的ではないことが証明されています。


13

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

Hibernateは、SQLを単純化し、データベーステーブルとJavaオブジェクトの真のマッピングを可能にし、階層関係がオブジェクトリレーションマッピングまたはORMと呼ばれるように反映されるようにしました。私はそれが好きだった。特に、ResultSetをJavaオブジェクトまたはデータ型にマップし直す必要はありませんでした。

Strutsが登場して、Model View ControllerパターンをWebアプリに追加しましたが、それは良かったです。

EJBは非常に大きなオーバーヘッドであり、苦痛と注釈によってコードは鶏のように見え、今やSpringが私たちに無邪気な人々をもたらしました。それは私には無理があるようです。

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

それとは対照的に、必要な接続を純粋なJavaで以下に示すように本当に簡単に行うことを検討してください。

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

それはそれ自体で説明が簡単であり、その大きなラウンドについて簡単に素早く簡単に行うことができ、他の大きな利点はありません。それは、とにかく本当に大切な小さな素敵な贈り物の周りにたくさんのギフト用紙を包むようなものです。

別の例は、バッチ更新です。Springでは、JdbcTemplateを使用してバッチ更新を行う前に、かなりの数のクラス、インターフェースを含む複雑なものになります。単純なjdbcの場合:

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

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

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


6
そのコードは単純ですが、トランザクション処理はどこで定義され、どのようにテストしますか?どちらも春までに簡単になります。また、接続URLとパスワードを外部に保存しない限り、Javaコードはdb接続に直接結び付けられます。これは、春によっても簡単になります。
ニムチンプスキー

この回答に+1、上記のコメントに対処するために、ユーザーは独自の軽量設計パターン(GOF)、接続プーリング用のシングルトン、データベースオブジェクトにSQL(文字列)と値(配列)を提供するプロキシクラス(どのメソッド、httpメソッドに依存します)、dbobjectは接続プーリング、トランザクションなどを処理し、クエリを実行してからリリースします。1つのオブジェクトがすべてのモジュールで使用されるため、過度のボイラープレートコードは必要ありません。プロキシクラスとdbobjectでユニットテストを設定することのボーナスポイント。
user2727195

ただし、Spring-Data-JPAをチェックしてください!pojoにエンティティに注釈を付け、インターフェイスを実装し、findHammerByWeight()などの適切な名前を使用してメソッドシグネチャを定義し、springがメソッドを実装して、他のすべてのビジネスサービスまたはコントローラークラスで使用できる注入可能なリポジトリを提供します。
mancini0

13

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

Springは今日と同じように、シンプルなフレームワークとして知られていましたが、完全なエコシステムです。

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

  • Spring Framework(例:依存性注入、AOP ...)

  • 春の雲

  • 春のデータ

  • 春のセキュリティ

  • 春バッチ

  • 春のソーシャル

エコシステムの全容については、こちらをご覧ください。プロジェクトをチェリーピックすることは可能です。そのため、DI 用のGoogle GuiceやSpring Securityなどを使用して、セキュリティ関連のことを処理できます。生態系全体に投資する必要はありません。

今日、Spring-framework自体は主に

  • 依存性注入

  • 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  |
+-----------------+-----------------------------------------+

...

一方、sparkdropwizardのようなフレームワークは、迅速なWebアプリ作成の出発点としても適しています。


1
非常に有益な答え!
GOXR3PLUS

同意、非常に良い答え。OP、あなたに同情します。また、クラスでコンストラクターを呼び出すことができるように、XMLファイルと2層のインダイレクションを追加してコードを「単純化」するSpringデモを見せてくれた人もいました。本当に良いプレゼンテーションであり、最終的には利点と欠点がどこにあるかが明らかになります
アダムヒューズ

4

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

Springについて学ぶには、Expert Spring MVCとWeb Flowが役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.