【Java開発】SpringでWebアプリを作成しよう(DI-依存性の注入)

Java入門
スポンサーリンク

こんにちは!しーま(@s59shima)です。

いつもブログをご覧いただきありがとうございます。

今回は、こんな悩みや疑問のある方に向けて記事を書きました。

読者
読者

DIを取り入れたアプリ開発だと、どんな特徴があるの!?

DI(依存性の注入)の特徴や実際の活用方法について知りたい方にはおすすめの記事です。

  • OS:Windows 10
  • JDK:OpenJDK 8
  • IDE:Spring Tools 4
  • Spring Boot:2.3

SpringでのWebアプリの作成手順

Webアプリの作成手順
  • STEP1

    無料で使用できる SpringTools4 について紹介します。ダウンロードから始まり各種設定(日本語化)までを詳しく解説します。

  • STEP2

    Springプロジェクトを作成し、Webアプリを実行するまでの手順を詳しく解説します。難しい設定などは特にありませんので、簡単に始められます。

  • STEP3

    Thymeleafというテンプレートを使用してhtmlファイルを作成します。Thymeleafを使用するための設定なども詳しく解説します。

  • STEP4

    Springで用意されている入力チェックを使用します。アノテーションを使用することで簡単に実装ができます。

  • STEP5
    DI-依存性の注入本記事はココ!

    DI(依存性の注入)の有・無パターン2つを比較しながら詳しく解説します。

DI(依存性の注入)の特徴

DI(Dependency Injection)とは、依存性の注入と言われています。

依存性の注入とは、依存している部分(クラス間の関係)を外(外部ファイル)から注入することです。

DI有り・無しパターンの構成を見てみましょう。

Webアプリを作成する場合、以下のような構成になります。

DI無しのパターン

3層構成に分かれているが、それぞれの層に依存している。

DI有のパターン

DIコンテナを活用し、各層の依存度が無くなり、結合度が下がる。

つまり、DI(依存性の注入)の特徴は

  • モジュール間の依存関係を弱くすることができる。
  • 各層(プレゼンテーション・ビジネス・永続化)で容易にテストが実施できる。

DI(依存性の注入)を理解する

上記の図の通り、DI有り・無しパターンを作成し、比較を行うことで理解を深めていきましょう。

下記のような簡易Webアプリを作成します。

顧客番号を入力し、対象顧客のポイントを表示する。

フォルダー・ファイル構成は下記のようにします。

プレゼンテーション層の作成

プレゼンテーション層・コントローラークラスを作成します。

ClientController.java

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.demo.service.ClientService;

@Controller
public class ClientController {

  private final ClientService clientService;

    public ClientController( ClientService clientService ) {
      this.clientService = clientService;
    }
	
    @ModelAttribute
    public ClientForm setUpForm() {
      return new ClientForm();
    }

    @RequestMapping("/input")
    public String index() {
      return "index.html";
    }

    @RequestMapping("/output")
    public String result(@Validated ClientForm clientForm, BindingResult bindingResult, Model model) {

      if (bindingResult.hasErrors()) {
        return "index.html";
      }

      String number = clientForm.getNumber();
      String point = clientService.findByNumber( clientForm.getNumber() );
		
      model.addAttribute( "number", number );
      model.addAttribute( "point", point );

      return "output.html";
    }
}

ビジネス層の作成

ビジネス層・サービスクラスを作成します。

ClientService.java

package com.example.demo.service;

public interface ClientService {
  String findByNumber( String number );
}

ClientServiceImpl.java

package com.example.demo.service;

import org.springframework.stereotype.Service;

import com.example.demo.repository.ClientRepository;

@Service
public class ClientServiceImpl implements ClientService {

  private final ClientRepository clientRepository;

  public ClientServiceImpl( ClientRepository clientRepository ) {
    this.clientRepository = clientRepository;
  }

  @Override
  public String findByNumber(String number) {
    String point = clientRepository.findByNumber( number );
    return point;
  }
}

永続化層の作成

永続化層・リポジトリクラスを作成します。

ClientRepository.java

package com.example.demo.repository;

public interface ClientRepository {
  String findByNumber( String number );
}

ClientRepositoryImpl.java

package com.example.demo.repository;

import org.springframework.stereotype.Repository;

@Repository
public class ClientRepositoryImpl implements ClientRepository {

  @Override
  public String findByNumber(String number) {

    String point = null;
    switch( number ) {
      case "10000":
        point = "500";
        break;

      case "10001":
        point = "800";
        break;

      case "10002":
        point = "1200";
        break;

      default:
        point = "登録されていません";
        break;
    }
    return point;
  }
}

UI(画面)の作成

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8">
    <title>顧客入力</title>
  </head>
  <body>
    <h1>顧客の入力</h1>
    <form method="POST" action="output.html" th:action="@{output}" th:object="${clientForm}" >
      <p>顧客番号</p>
      <input type="text" name="number" th:field="*{number}">
      <p style="color:red;" th:errors="${clientForm.number}" class="error">顧客番号の入力チェック</p>
      <br>
      <input type="submit" name="登録">
    </form>
  </body>
</html>

output.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8">
    <title>顧客確認</title>
  </head>
  <body>
    <h1>顧客の確認</h1>
    <p>顧客番号 <span th:text="${number}"> 100</span></p>
    <p>ポイント数 <span th:text="${point}"> 100</span></p>
    <a href="index.html" th:href="@{input}"> 顧客入力に戻る</a>
  </body>
</html>

まとめ

今回は、DI(依存性の注入)について解説しました。

最後まで読んでいただきありがとうございます(*^-^*)

本記事をまとめると以下の通りです。

【DI(依存性の注入)の特徴】

  • モジュール間の依存関係を弱くすることができる。
  • 各層(プレゼンテーション・ビジネス・永続化)で容易にテストが実施できる。

関連記事

しーま
しーま

プログラミングスクールの【Raise Tech】では、Spring Frameworkを使った実践コースが受講できます。今すぐスキルを身に付けたい方は必見ですね!

Javaスキルで悩んでいる方必見!本気で学習できる環境を探してみよう!
詳細はこちら
Javaスキルで悩んでいる方必見!本気で学習できる環境を探してみよう!
詳細はこちら
タイトルとURLをコピーしました