JavaフレームワークとしてSpringを選択する理由

1. 概要

この記事では、最も人気のあるJavaフレームワークの1つとして、https://spring.io/ [Spring]の主な価値提案を紹介します。
さらに重要なことは、Springが私たちのフレームワークである理由を理解しようとすることです。 Springとその構成部分の詳細は、https://www.baeldung.com/spring-intro [以前のチュートリアルで幅広く取り上げられています]。 したがって、入門的な「方法」の部分は省略し、主に「理由」に焦点を当てます。

2. フレームワークを使用する理由

特にSpringで議論を始める前に、まずフレームワークを使用する必要がある理由をまず理解しましょう。
  • Javaのような汎用プログラミング言語は、さまざまなアプリケーションをサポートできます*。 Javaが日々活発に取り組んでおり、改善していることは言うまでもありません。

    さらに、この点でJavaをサポートするための無数のオープンソースおよび独自のライブラリがあります。
    では、なぜフレームワークが必要なのでしょうか? 正直なところ、フレームワークを使用してタスクを完了する必要はありません。 しかし、いくつかの理由で使用することをお勧めします。
  • ボイラープレートではなくコアタスクに焦点を当てるのに役立ちます
    それに関連付けられている

  • 長年の知恵をデザインパターンの形でまとめる

  • 業界および規制基準への準拠を支援します

  • アプリケーションの総所有コストを削減します

    ここで表面をかき分けただけなので、メリットを無視するのは難しいと言わなければなりません。 しかし、すべてがプラスになるわけではないので、キャッチは何ですか:
  • 特定の方法でアプリケーションを作成するように強制します*

  • 特定のバージョンの言語とライブラリにバインドします

  • アプリケーションのリソースフットプリントに追加します

    率直に言って、ソフトウェア開発に特効薬はなく、フレームワークも確かに例外ではありません。 したがって、どのフレームワークを選択するか、どのフレームワークを選択するかは、コンテキストから決定されるべきです。
    願わくば、この記事の終わりまでに、JavaのSpringに関してこの決定を下せるようになります。

3. Spring Ecosystemの概要

Spring Frameworkの定性的評価を始める前に、Springエコシステムがどのようなものかを詳しく見てみましょう。
  • Springは、Java Enterprise Editionが急速に進化し、エンタープライズアプリケーションの開発がエキサイティングであったにもかかわらず、退屈であった2003年のどこかに出現しました!

    Springはlink:/inversion-control-and-dependency-injection-in-spring[Javaの制御の反転(IoC)コンテナー]として始まりました。 まだSpringを大部分に関連付けており、実際、それはフレームワークのコアを形成し、その上で開発された他のプロジェクトを形成しています。

3.1. 春のフレームワーク

Springフレームワークはhttps://docs.spring.io/spring/docs/current/spring-framework-reference/index.html [モジュールに分割]であり、アプリケーションで使用するパーツを簡単に選択できます。
  • Core
    DI(依存性注入)、国際化、検証、AOP(アスペクト指向プログラミング)などのコア機能を提供します

  • Data
    アクセス
    :JTA(Java Transaction API)、JPA(Java Persistence API)、およびJDBC(Java Database Connectivity)を介したデータアクセスをサポートします。

  • Web
    サーブレットAPI(https://docs.spring.io/spring/docs/5.1.8.RELEASE/spring-framework-reference/web.html#spring-web[Spring MVC])と最近リアクティブAPI(https ://docs.spring.io/spring/docs/5.1.8.RELEASE/spring-framework-reference/web-reactive.html#spring-webflux [Spring WebFlux])、さらにWebSocket、STOMP、およびWebClientをサポート

  • Integration
    JMS(Java Message Service)、JMX(Java Management Extension)、およびRMI(Remote Method Invocation)を介したエンタープライズJavaへの統合をサポート

  • https://docs.spring.io/spring/docs/5.1.8.RELEASE/spring-framework-reference/testing.html#testing [テスト]:
    モックオブジェクト、テストフィクスチャ、コンテキスト管理、キャッシングによるユニットおよび統合テストの幅広いサポート

3.2. 春のプロジェクト

しかし、Springの価値を高めているのは、*長年にわたってSpringを中心に成長し、積極的に進化し続けている強力なエコシステム*です。 これらは、https://spring.io/projects [Springプロジェクト]として構造化され、Springフレームワーク上で開発されます。
Springプロジェクトのリストは長く、変化し続けていますが、言及する価値のあるものがいくつかあります。
  • Boot:のセットを提供します
    Springに基づいてさまざまなプロジェクトをすぐに作成するための、非常に意見が豊富で拡張可能なテンプレート。 Tomcatまたは同様のコンテナが組み込まれたスタンドアロンのSpringアプリケーションを簡単に作成できます。

  • link:/spring-cloud-tutorial [クラウド]:提供
    サービス検出、サーキットブレーカー、APIゲートウェイなどの一般的な分散システムパターンのいくつかを簡単に開発するためのサポート。 このような定型パターンをローカル、リモート、さらには管理されたプラットフォームに展開する労力を削減するのに役立ちます。

  • link:/security-spring [セキュリティ]:堅牢な
    Springに基づくプロジェクトの認証と承認を高度にカスタマイズ可能な方法で開発するメカニズム。 最小限の宣言的サポートにより、セッション固定、クリックジャッキング、クロスサイトリクエストフォージェリなどの一般的な攻撃から保護されます。

  • Mobile:機能を提供します
    デバイスを検出し、それに応じてアプリケーションの動作を調整します。 さらに、最適なユーザーエクスペリエンスのためのデバイス対応のビュー管理、サイト設定管理、およびサイト切り替えをサポートします。

  • Batch:提供
    データアーカイブなどのエンタープライズシステム用のバッチアプリケーションを開発するための軽量フレームワーク。 スケジューリング、再起動、スキップ、メトリックの収集、およびロギングを直感的にサポートします。 さらに、最適化とパーティション分割による大容量ジョブのスケールアップをサポートします。

    言うまでもなく、これは、Springが提供するもののかなり抽象的な紹介です。 ただし、Springの組織と幅に関して十分な基盤を提供し、議論をさらに進めます。

4. アクションの春

新しいテクノロジを理解するために、hello-worldプログラムを追加するのが慣例です。
  • Springを使用して、単なるhello-world *以外のことを実行するプログラムを作成することができます。 インメモリデータベースを基にしたEmployeeなどのドメインエンティティのREST APIとしてCRUD操作を公開するアプリケーションを作成します。 さらに、基本認証を使用してミューテーションエンドポイントを保護します。 最後に、適切な古い単体テストなしでは、アプリケーションを完全に完成させることはできません。

4.1. プロジェクトのセットアップ

https://start.spring.io/[Spring Initializr]を使用してSpring Bootプロジェクトを設定します。これは、適切な依存関係を持つプロジェクトをブートストラップする便利なオンラインツールです。 プロジェクトの依存関係としてWeb、JPA、H2、およびセキュリティを追加して、Maven構成を正しくセットアップします。
link:/spring-boot-start [ブートストラップの詳細]は、以前の記事のいずれかで入手できます。

4.2. ドメインモデルと永続性

実行することはほとんどないため、ドメインモデルと永続性を定義する準備はすでに整っています。
最初に_Employee_を単純なJPAエンティティとして定義しましょう:
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @NotNull
    private String firstName;
    @NotNull
    private String lastName;
    // Standard constructor, getters and setters
}
エンティティ定義に含めた自動生成IDに注意してください。
ここで、エンティティのJPAリポジトリを定義する必要があります。 これは、Springが本当にシンプルにするところです。
public interface EmployeeRepository
  extends CrudRepository<Employee, Long> {
    List<Employee> findAll();
}
私たちがしなければならないことは、このようなインターフェースを定義することだけです。* Spring JPAは、デフォルトおよびカスタム操作で具体化された実装を提供します*。 とてもすてき! 詳細については、https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa [Spring Data JPAの操作]の他の記事をご覧ください。

4.3. コントローラ

次に、着信リクエストをルーティングおよび処理するWebコントローラーを定義する必要があります。
@RestController
public class EmployeeController {
    @Autowired
    private EmployeeRepository repository;
    @GetMapping("/employees")
    public List<Employee> getEmployees() {
        return repository.findAll();
    }
    // Other CRUD endpoints handlers
}
本当に、私たちがしなければならなかったことは、クラスに注釈を付けて、各ハンドラーメソッドと共にルーティングメタ情報を定義することだけでした。
link:/building-a-restful-web-service-with-spring-and-java-based-configuration[Spring REST controllers]の操作については、前の記事で詳しく説明しています。

4.4. セキュリティ

これですべてを定義できましたが、従業員の作成や削除などの操作の保護についてはどうでしょうか? これらのエンドポイントへの認証されていないアクセスは望ましくありません!
Spring Securityはこの分野で非常に優れています。
@EnableWebSecurity
public class WebSecurityConfig
  extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http)
      throws Exception {
        http
          .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/employees", "/employees/**")
            .permitAll()
          .anyRequest()
            .authenticated()
          .and()
            .httpBasic();
    }
    // other necessary beans and definitions
}
理解するにはlink:/spring-security-basic-authentication [注意が必要な詳細]がありますが、注意する最も重要なポイントは* GET操作のみを無制限に許可する宣言的な方法です*。

4.5. テスト

これですべてが完了しましたが、待って、これをどのようにテストしますか?
SpringでRESTコントローラーの単体テストを簡単に作成できるかどうかを見てみましょう。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class EmployeeControllerTests {
    @Autowired
    private MockMvc mvc;
    @Test
    @WithMockUser()
    public void givenNoEmployee_whenCreateEmployee_thenEmployeeCreated() throws Exception {
        mvc.perform(post("/employees").content(
            new ObjectMapper().writeValueAsString(new Employee("First", "Last"))
            .with(csrf()))
          .contentType(MediaType.APPLICATION_JSON)
          .accept(MediaType.APPLICATION_JSON))
          .andExpect(MockMvcResultMatchers.status()
            .isCreated())
          .andExpect(jsonPath("$.firstName", is("First")))
          .andExpect(jsonPath("$.lastName", is("Last")));
    }
    // other tests as necessary
}
ご覧のとおり、* Springは、初期化および構成するSpringコンテキストに依存する単純な単体テストおよび統合テスト*を作成するために必要なインフラストラクチャを提供します。

4.6. アプリケーションを実行する

最後に、このアプリケーションをどのように実行しますか? これは、Spring Bootのもう1つの興味深い側面です。 ただし、これを通常のアプリケーションとしてパッケージ化し、従来どおりサーブレットコンテナにデプロイできます。
しかし、これはどこが楽しいですか! * Spring BootにはTomcatサーバーが組み込まれています*:
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
これは、ブートストラップの一部として事前に作成されたクラスであり、組み込みサーバーを使用してこのアプリケーションを開始するために必要なすべての詳細が含まれています。
さらに、https://www.baeldung.com/spring-boot-application-configuration [これは高度にカスタマイズ可能です]。

5. 春の代替品

フレームワークの使用を選択することは比較的簡単ですが、フレームワークから選択することは、多くの場合、私たちが持っている選択で困難になる場合があります。 しかし、そのためには、Springが提供しなければならない機能に対して、どのような選択肢があるのか​​を少なくとも大まかに理解する必要があります。
前述したように、* Springフレームワークとそのプロジェクトは、エンタープライズ開発者が選択できる幅広い選択肢を提供します*。 現代のJavaフレームワークをすばやく評価すると、Springが提供するエコシステムに近づきさえしません。
ただし、特定の領域については、選択肢として選択する説得力のある議論を形成しています。
  • Guice:堅牢なIoCコンテナーを提供します
    Javaアプリケーション用

  • Play:かなり
    リアクティブサポートを備えたWebフレームワークとして適切に適合

  • Hibernate:確立された
    JPAサポートを使用したデータアクセスのフレームワーク

    これら以外に、特定のドメインよりも幅広いサポートを提供するが、Springが提供するすべてをカバーしていない最近の追加がいくつかあります。
  • Micronaut:JVMベースのフレームワーク
    クラウドネイティブのマイクロサービス向けにカスタマイズ

  • Quarkus:新しい時代のJavaスタック
    これにより、起動時間の短縮と設置面積の削減が約束されます

    明らかに、リストを完全に反復処理することは必要でも実行可能でもありませんが、ここで幅広いアイデアを得ています。

6. それでは、なぜ春を選ぶのですか?

最後に、私たちの中心的な質問であるSpringに対処するために必要なコンテキストをすべて構築しました。 フレームワークが複雑なエンタープライズアプリケーションの開発に役立つ方法を理解しています。
さらに、Web、データアクセス、フレームワークの観点からの統合、特にJavaのような特定の懸念に対して、私たちが持っているオプションを理解しています。
さて、これらすべての中で春はどこで輝いていますか? 探検しましょう。

6.1. 使いやすさ

フレームワークの人気の重要な側面の1つは、開発者がフレームワークを使用するのがどれほど簡単かということです。 複数の設定オプションと設定を介した規約により、開発者は必要なものを正確に開始し、設定することが非常に簡単になります*。
  • Spring Bootのようなプロジェクトにより、複雑なSpringプロジェクトのブートストラップがほとんど簡単になりました*。 言うまでもなく、誰でも参加できるように役立つ優れたドキュメントとチュートリアルがあります。

6.2. モジュール性

Springの人気のもう1つの重要な側面は、その高度なモジュール性です。 Springフレームワーク全体を使用するか、必要なモジュールのみを使用するかを選択できます。 さらに、必要に応じて、オプションで1つ以上のSpringプロジェクトを含めることができます。
さらに、HibernateやStrutsなどの他のフレームワークを使用するオプションもあります!

6.3. 適合性

SpringはすべてのJava EE仕様をサポートしているわけではありませんが、すべてのテクノロジーをサポートしており、必要に応じて標準仕様よりもサポートを改善することがよくあります。 たとえば、SpringはJPAベースのリポジトリをサポートしているため、プロバイダーの切り替えは簡単です。
さらに、Springは、Spring Web Reactiveのhttps://www.reactive-streams.org/[Reactive Stream]やlink:/spring-hateoas-tutorial[Spring HATEOAS]のHATEOASなどの業界仕様をサポートしています。

6.4. テスト容易性

フレームワークの採用は、その上に構築されたアプリケーションのテストがどれほど簡単かという事実にも大きく依存しています。 Springは中心にあり、テスト駆動開発(TDD)を提唱しサポートしています。
SpringアプリケーションはほとんどがPOJOで構成されているため、当然、ユニットテストは比較的簡単です。 ただし、Springは、単体テストが複雑になるMVCのようなシナリオにモックオブジェクトを提供します。

6.5成熟度

Springには、革新、採用、標準化の長い歴史があります。 長年にわたり、大規模なエンタープライズアプリケーションの開発で直面する最も一般的な問題のデフォルトソリューションになるのに十分なほど成熟しました。
さらにエキサイティングなのは、どれだけ積極的に開発および保守されているかです。 新しい言語機能とエンタープライズ統合ソリューションのサポートは毎日開発されています。

6.6. コミュニティサポート

最後になりましたが、フレームワークやライブラリでさえ、イノベーションを通じて業界を生き残ります。そして、コミュニティ以上にイノベーションの場はありません。 Springは、Pivo​​tal Softwareが主導するオープンソースであり、組織と個々の開発者の大規模なコンソーシアムによって支援されています*。
これは、その傘下のプロジェクトの数から明らかなように、文脈的であり、しばしば未来的であることを意味しています。

7. Springを使用しない理由

さまざまなレベルのSpringの使用から恩恵を受けることができるさまざまなアプリケーションがあり、それはSpringの成長に合わせて急速に変化しています。
ただし、Springは他のフレームワークと同様に、アプリケーション開発の複雑さを管理するのに役立つことを理解する必要があります。 一般的な落とし穴を回避し、時間とともに成長するアプリケーションを維持できるようにします。
これは、追加のリソースフットプリントと学習曲線*のコストがかかりますが、どんなに小さくてもかまいません。 本当に単純で、複雑になるとは思われないアプリケーションが本当にある場合、フレームワークをまったく使用しないほうがよいかもしれません!

8. 結論

この記事では、アプリケーション開発でフレームワークを使用する利点について説明しました。 特にSpring Frameworkについてさらに簡単に説明しました。
このテーマについては、Javaで利用可能な代替フレームワークのいくつかも検討しました。
最後に、JavaのフレームワークとしてSpringを選択せざるを得ない理由について説明しました。
ただし、この記事はアドバイスのメモで終了する必要があります。 しかし、説得力があるように聞こえるかもしれませんが、*ソフトウェア開発には、通常、単一の万能ソリューションはありません*。
したがって、解決する特定の問題に対して最も単純なソリューションを選択する際に、知恵を適用する必要があります。