DI/AOP

Spring BootでDIを利用してみた

Springフレームワークの基本として、DI(Dependency Injection)という概念がある。

DIは日本語で「依存性の注入」といい、newを使わなくてもオブジェクトを生成してくれる仕組みのことをいう。このDIを利用すると、プログラム間での依存関係を薄くすることができるため、ソフトウェアの品質を高めることにつながる。

今回は、サンプルプログラムを通して、Springを利用したJavaの開発現場でよく使われる、アノテーションベースでのDIの具体的な実装方法について共有する。

前提条件

以下の記事のSpring BootのWEB画面用アプリが作成済であること。

IntelliJ IDEA上でGradleを使ってWeb画面のSpring Bootプロジェクトを作成してみたSpring Bootのプロジェクトを新規作成を「IntelliJ IDEA」のメニューから実施しようとしたところ、無料の「Commun...

 

やってみたこと

  1. DIを使わない実装
  2. Componentアノテーションを利用した実装
  3. Component以外のアノテーションを利用した実装

 

DIを使わない実装

他のクラスのオブジェクトを生成する際、DIを使わず、通常のnewを利用することができる。以下にそのサンプルプログラムの構成を示す。
DIを使わないプログラムの構成

下記DemoController.java内では、「DemoObject」クラスのメソッドを呼び出すソースコードになっていて、DIを使わず、通常のnewを利用している。

ちなみに、DemoController.java内の「mav.setViewName(“index”);」で、遷移先画面「templates/index.html」を指定し、また「mav.addObject(“fromStr”, str);」で遷移先画面で表示する文字例fromStrを設定している。



また、下記index.html内で、「DemoObject」クラスのメソッドから取得した文字列「fromStr」を表示している。

index.html内の「xmlns:th=”http://www.thymeleaf.org/”」でthymeleafを読み込み、「th:text=”${fromStr}”」で、DemoController.javaで設定したformStrを表示している。

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-di/no_di/demo

作成したSpring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスした結果は以下の通り。
DIを使わない場合の実行結果

Componentアノテーションを利用した実装

他のクラスのオブジェクトを生成する際、Dlを利用すると、newを利用しなくて良いため、クラス間の依存度を小さくすることができる。以下にそのサンプルプログラムの構成を示す。
Componentアノテーションを利用したプログラムの構成

下記のDemoController.java内で、DemoComponent.javaクラスのメソッドを呼び出すソースコードになっていて、newを使わずDIを利用して、DemoComponentオブジェクトを生成している。

DemoComponent.javaではアノテーション@Componentを付与し、DemoController.javaでDemoComponentオブジェクトに@Autowiredを付与することで、Dlによるオブジェクトの生成が行えるようになっている。なお、index.htmlはDlを使わない実装と同じなので、記載を省略する。

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-di/use_component/demo

作成したSpring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスした結果は以下の通り。
Componentアノテーションを利用した場合の実行結果



Component以外のアノテーションを利用した実装

DIを利用するアノテーションは、@Component以外も利用することができる。今回は、@Repository、@Service、@Controllerを利用したサンプルを掲載する。

@Repository、@Service、@Controller のアノテーションの使い分けについては以下のサイトを参照のこと。
https://qiita.com/KevinFQ/items/abc7369cb07eb4b9ae29

上記サイトに記載されている通り、一般的には、データ層のクラスには@Repositoryを、サービス層のクラスには@Serviceを、コントローラ層のクラスには@Controllerを付与するが、それぞれのアノテーションの役割は@Componentと同じである。

今回のサンプルコードの構成は以下の通り。
Componentアノテーション以外のDIを利用した場合のプログラムの構成

Javaのソースコードそれぞれの内容は以下の通り。なお、index.htmlはDlを使わない実装と同じなので、記載を省略する。

DemoRepository.javaでアノテーション@Repositoryを、DemoService.javaでアノテーション@Serviceを、DemoSubController.javaでアノテーション@Controllerを付与し、DemoController.javaで、DemoRepository.java、DemoService.java、DemoSubController.javaの各オブジェクトに@Autowiredを付与することで、Dlによるオブジェクトの生成が行えるようになっている。

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-di/use_others/demo

作成したSpring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスした結果は以下の通り。
Componentアノテーション以外のDIを利用した場合の実行結果

要点まとめ

  • DIを利用すると、プログラム間での依存関係を薄くすることができる。
  • クラスの先頭に「@Component」を付与すると、DIするオブジェクトの生成対象とすることができる。「@Repository」「@Service」「@Controller」も同じ役割をもつ。
  • DIするオブジェクトを生成し利用するには、「@Autowired」アノテーションを利用する。