
SpringFrameworkの海に飛び込んでみた
2022.11.14
はじめに
はじめまして!7月に入社した武田と申します。
10月から参入する案件でSprignBootを使うということで、現在キャッチアップをしています。その中で度々「DI」という言葉が出てきたので、その周辺概念をざっくり整理してみました。
DI(Dependency Injection)とは
直訳すると「依存性の注入」で、これはクラス間の依存関係を付与するアクションになります。
依存関係を持たせると聞いて、「クラスAの中でクラスBをインスタンス化させるだけのことでは?」と思っていました。
1 2 3 4 5 6 7 8 | public class A { private B b; // コンストラクタでクラスBのインスタンスを生成 public A() { b = new B(); } } |
このようにクラスAがクラスBを直接参照するようにしてしまうと、クラスBが具象クラスであること等の制約が生またりと、クラスBを修正した際にクラスAも修正が必要になる可能性が生まれます。(密結合になりがち)
そこで、「依存関係の制御を、開発者(の作成したクラス)からSpringFramework側に移してしまおう」というのがDIのようです。
具体的には、上の例ですと、クラスAとクラスBの間に「Spring IoCコンテナ」が仲介します。
イメージ
このようにSpring IoCが間にいるおかげで、クラスAはクラスBのインスタンス生成方法を知る必要がなくなり、疎結合になりました。
制御の反転(IoC)
従来制御していた側が制御される側に回るということで、DIはこの概念の具体的なものに当たるようです。
コンピュータプログラミングの用語で制御の反転(Inversion of Control、IoC )とは、なんらかの種類のプログラムにおいて、プロシージャを「呼び出す側」と「呼び出される側」が、従来のプログラムとは逆になるようにする
DIは、オブジェクト(の依存関係)の制御が、開発者が書いたコードからSpringというフレームワーク側に移す行為という感じでしょうか。
そのためすごく乱暴に言ってしまえば、ここではIoC≒DIというイメージで問題ないのかなと思います。
Spring IoCコンテナとBean
DIを行うためにはDIしたいクラスを登録する必要があります。 Spring IoCコンテナで管理するクラスをBeanという単位で扱います。
Spring IoCコンテナはBeanをインスタンス化し、依存性注入を行います。
また、どのBean同士がどんな関係性を持つのかは「設定メタデータ」を参照します。
この設定メタデータは、「XML」、「Javaアノテーション」、「Javaコード」で表現が可能となっています。
設定例
XMLベースの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <code class="language-java"><?xml version="1.0" encoding="UTF-8"?> <beans xmlns="<http://www.springframework.org/schema/beans>" xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>" xsi:schemaLocation="<http://www.springframework.org/schema/beans> <https://www.springframework.org/schema/beans/spring-beans.xsd>"> <!-- services --> <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"> <property name="accountDao" ref="accountDao"/> <property name="itemDao" ref="itemDao"/> <!-- additional collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions for services go here --> </beans></code> |
Javaベース/アノテーションベースの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @Configuration public class AppConfig { @Bean public ClientService clientService1() { ClientServiceImpl clientService = new ClientServiceImpl(); clientService.setClientDao(clientDao()); return clientService; } @Bean public ClientService clientService2() { ClientServiceImpl clientService = new ClientServiceImpl(); clientService.setClientDao(clientDao()); return clientService; } @Bean public ClientDao clientDao() { return new ClientDaoImpl(); } } </code><a href="https://spring.pleiades.io/spring-framework/docs/current/reference/html/core.html#beans-factory-xml-import"></a> |
イメージ
SpringBoot
SpringBootはSpringFrameworkを手軽に始められるようにしたもので、上述のXMLによる設定や、「@」から始まる「アノテーション」を使った設定用クラスを作成しなくてもSpringFrameworkの機能を使えるようになります。
上述のBean定義(どのクラスをBeanとしてIoCコンテナに登録するか)についてですが、mainメソッドのあるクラスに@SpringBootApplicationアノテーションをつけることで、登録をほぼ自動化できてしまいます。
例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package payroll; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * メインクラス */ @SpringBootApplication public class PayrollApplication { /** * プログラム実行の起点となるメソッド * @param args */ public static void main(String... args) { SpringApplication.run(PayrollApplication.class, args); } } |
@SpringBootApplicationは以下のアノテーションを内包しています。
- @EnableAutoConfiguration: Springアプリケーションの自動設定を行う。
- @ComponentScan:@Componentアノテーション(またはこれを含む、@Controller,@Service,@Repositoryアノテーション)が付いているクラスを読み込む
- @Configuration: Spring IoCに追加の Bean を登録する。
つまり、このアノテーションを付けるだけで上述の設定をほぼ自動で行ってくれる形になります。
おわり
初めてSpringFrameworkを触るということで、「DI」を軸に基本的な概念や用語についてドキュメントを読んで学んでみました。
チュートリアルで作ったソースコードを改めて見返すと、理解できる部分が増えていたので嬉しかったです。
最後に、今回学習に使用したドキュメントを以下にまとめて終わりにしようと思います。ありがとうございました!
【SpringFramework概要】
Spring Framework の概要 - リファレンスドキュメント
【コア概念】
Spring Framework コアテクノロジー - リファレンス
【SpringBootの使用】
Spring Boot での開発 - リファレンスドキュメント
書いた人はこんな人

- 2022年7月に入社しました。開発未経験で未知の領域だらけですが、楽しく学びつつ、早く戦力になれるようにがんばります!
IT技術8月 4, 2023TDD入門してみた by Laravel
IT技術6月 12, 2023型に詳しくなりたいのでPHPの勉強会に参加してみた
IT技術12月 27, 2022Homebrewで過去バージョンのパッケージをインストールする手順
IT技術10月 5, 2022SpringFrameworkの海に飛び込んでみた