Spring Bootの基本のキ

## 始めに
こんにちは。
今回はSpringBootを一から勉強したので、学んだことをできるだけ噛み砕いて自分なりにまとめてみました。
この記事では具体的な実装方法は説明しないので、「まずはSpring Bootがどのようなものなのかなんとなく知りたい」と思っている方に活用していただけると幸いです。
### この記事の対象者
・Spring Bootの学習を始めた方
・Spring Bootとはそもそも何か知りたい方
・Javaの概要を理解している方

### この記事で伝えること
・Spring Bootとは何か
・Spring Bootの特徴（DI・AOP）

## Spring Bootとは？
まずは、そもそもSpring BootとはどのようなものかSpring Frameworkと共に説明します。

### Spring Frameworkとは？
Java開発において利用できるフレームワークの __集合体__ のこと。
※「Spring」と縮めて呼ばれているものは、Spring Frameworkのことを指している。

Spring Frameworkは開発を効率化するための様々な機能を提供しており、それぞれの機能ごとにフレームワークが存在している。
そのため実現したいシステムに応じて使用するフレームワークを選ぶことができる。

|  フレームワーク  |  提供する機能の概要  |
| ---- | ---- |
|  Spring MVC  |  Webアプリケーションを簡単に作成する機能を提供  |
|  Spring Data  |  データアクセスに関する機能提供  |
|  Spring Batch  |  バッチ処理機能を提供  |
|  Spring Security  |  認証認可の機能を提供  |

※「フレームワーク」とは
開発を簡単にするための「骨組み」のこと。
フレームワークを使うことで全てのプログラムを一から作る必要がないため、開発効率が上がる。

### Spring Bootとは？
Spring Frameworkに含まれるフレームワークの一つで、 __Spring Frameworkの機能を使いやすくするため__ のフレームワーク。

![Spring全体像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/72f2dc5a-9654-faf2-9292-e5a02362d023.png)

Spring Frameworkは各フレームワークを使用するにあたってXMLファイル等の用意が必要であり、様々なフレームワークを提供しているが故に、環境設定が複雑になってしまうという問題があった。

これを解消するために作られたのがSpring Bootで、Spring Bootでは使いたい機能を選ぶだけで自動で初期設定を行ってくれる。
![springframework違い.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/9a164850-89ba-b0be-fa41-f565215c281c.png)



## SpringBootプロジェクトの立ち上げ方法
eclipse(Pleiades ALL in One)でのSpring Bootプロジェクトの作成方法を簡単に説明します。

①パッケージ・エクスプローラーで右クリックし、「新規」>「Spring スターター・プロジェクト」を選択
![操作1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/24a0312a-b5b5-1da9-1d5e-9fbc6af1520e.png)


②「名前」「タイプ」「パッケージ」などを任意に設定して「次へ」
![操作2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/a802ef60-6cec-83eb-d045-e74ec53f82ec.png)


③Spring BootのバージョンとSpring Bootプロジェクトで使用する機能を選択し、「次へ」
![操作3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/16789db4-58b9-cec3-1743-d40fc3f0be45.png)


④プロジェクトが作られる
![操作4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/b61e1ac1-ab81-8445-0475-79cd002f3855.png)


※今回はビルドツールとしてMavenを選んだため、作成したプロジェクト配下にpom.xmlが自動で生成されている。
pom.xmlを見てみると、③で選択した機能がdependency(依存関係)として定義されていることがわかる。
![操作5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/d3a1ebd1-0594-ae9c-5245-eb6c27ac3c91.png)



## SpringBootの特徴
ここからはSpringBoot（正しくはSpring Framework）のコア機能である __「DI」__ と __「AOP」__ について説明します。
結論、この二つの機能は __「システムの開発効率・保守性を高める」__ ためのものです。
### ①DI
「Dependency Injection」の略で、「依存性の注入」と訳される。
この機能を「DIコンテナ」が担っている。

#### 「依存性」とは？
「依存性」とは、 __あるクラス（＝使う側）が他のクラス（＝使われる側）を利用している__ こと。

Javaには以下2種類の依存がある。
この2種類の依存では、「使われる側クラス」に変更があった場合、 __「使う側クラス」の修正が必要__ になる。

##### 1. クラス依存
「使う側クラス」で「使われる側クラス」をインスタンス化し、メソッドを呼び出すこと。

__【「使われる側クラス」に修正が入った場合】__
①「使われる側クラス」のインスタンスを代入する変数の型の修正
②「使われる側クラス」のインスタンス化処理の修正
③「使われる側クラス」のメソッド呼び出し処理を修正
![クラス依存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/7b1faf65-92c0-9ae8-518d-3bd8114e6def.png)


##### 2. インターフェース依存

「使う側クラス」で「使われる側クラス」をインターフェース型でインスタンス化し、メソッドを呼び出すこと。

__【「使われる側クラス」に修正が入った場合】__
①「使われる側クラス」のインスタンス化処理の修正
![インターフェース依存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/df3f44ed-e0c8-323c-c127-6aed3083e4de.png)




このように、Javaには2種類の依存があるが、「インターフェース依存」は「クラス依存」よりも修正箇所が少なくなり、「__低依存__」な状態にできるというメリットがある。

しかし、「インターフェース依存」でも「使う側クラス」の修正は必要であり、
「使う側クラス」が複数ある場合、修正漏れが起こる可能性が出てしまう。
この問題を解消してくれるのがDIの機能。

#### DIコンテナの役割
DIコンテナは __「使われる側クラス」をインスタンス化し、そのインスタンスを「使う側クラス」に注入__ する。
「クラス依存」と「インターフェース依存」に置いて、インスタンス生成はnewキーワードを用いて「使う側クラス」で行っているが、このインスタンス生成を代わりに行ってくれるのがDIコンテナ。
※生成されたインスタンスは「Bean」と呼ばれる

![DIコンテナ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/c926a025-8da2-08b2-6c1f-56a9d952b680.png)



#### DIプログラムの実装
DIコンテナにインスタンス生成を行ってもらい、そのインスタンスを利用するために必要なのは、下記のように「__アノテーションを付与する__」ことである。

__①使われる側クラスに 「@Component 」アノテーションを付与する__
　※「@Controller」「@Service」「@Repository」もインスタンス生成アノテーション。
__②使う側クラスで、インスタンスの参照を受け取るためのフィールドを宣言し、フィールドに 「@Autowired」アノテーションを付与する__

Spring Bootは起動時に、「@Component」など対象のアノテーションが付与されたクラスを探し、インスタンス化する。それらをDIコンテナに登録しておき、「@Autowired」が付与されている箇所に注入している。

![DI実装1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/4abfa011-4a19-d59a-9332-a833ccb5f1ba.png)


#### DIのメリット
 - __「使う側クラス」の修正が不要になる__
DIコンテナにインスタンス化を行ってもらうことで、「使われる側クラス」に修正が入った場合でも、__「使う側クラス」の修正は不要__ になる。
「使われる側クラス」に付与しているアノテーションを修正するだけで、「使う側クラス」で使用したいインスタンスを変えることができる。
![DI実装.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/245a2a7a-f1a3-8074-4e78-02dd2cd87a06.png)



### ②AOP
「Aspect Oriented Programming」の略で、「アスペクト指向プログラミング」と訳される。

#### 「アスペクト指向プログラミング」とは？
アスペクト指向プログラミングとは、簡単に説明すると「 __共有する処理を抜き出してまとめて管理する仕組み__ 」のこと。

アスペクト指向では、プログラムは以下の二つの要素で構成されていると考える。
![AOP概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/1f214c15-6c9e-c8c1-133d-9d4f5f98ab4f.png)



「横断的関心事」とは、実現したい機能の本質的な部分ではないが、
品質・保守の観点で必要になるもののことで、データベース接続後の例外処理や、ログ出力処理などを指す。

「中心的関心事」・「横断的関心事」をまとめて記述すると、以下のようなデメリットがある。
- __処理が増えることでソースが読みづらくなる__
- __処理を入れ忘れる可能性がある__

これを防ぐために、 __「中心的関心事」と「横断的関心事」を分け、「横断的関心事」をまとめて管理する__ のがAOPの機能である。

![AOPイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/6c83d654-d7e4-5abe-971b-3c3a8071724a.png)


#### AOPの実装
まずはAOPを理解するにあたり、知っておく必要がある用語を紹介する。

|  用語  |  意味  |
| ---- | ---- |
|  Advice  |  横断的関心事を実装したメソッド  |
|  Aspect  |  Adviceをまとめたクラス |
|  JointPoint  |  Adviceを実行するタイミング<br> ※メソッドの実行前・実行後などを指定できる|
|  PointCut  |  Adviceを実行する場所（クラスやメソッド）<br>※「メソッド名がgetで始まるもの」といった条件を指定できる |

横断的関心事を記述するAspectクラスには、 __「@Aspect」「@Component」__ アノテーションを付与する。
各Adviceでは、JointPointとPointCutを指定することで、処理がいつ・どこで実行されるかを決める。
![AOP実装.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/c25c8fd1-a73c-fac9-f70b-2ad093ed6314.png)


```:JonitPointとPointCutの指定例
@Before(“execution(* com.example.Controller.get*(..))”)
```
= com.example.Controllerクラス配下の名前が __getから始まるメソッド__ の __前__ に実行する

#### AOPのメリットとは？
- __共有処理を統一化できる__
処理を1箇所にまとめることで、担当者によって実装が異なるといった状況を防ぐことができる。
また、共通処理に修正が入った場合も1箇所を修正すれば良いため、修正漏れを防ぐことができる。


- __コードの可読性が上がる__
横断的関心事を共通処理として抜き出すことで、処理の長さを短くすることができる。


- __開発効率が上がる__
作成したプログラムの動作確認をするために、全てのメソッドに確認用のログを入れる場合を考えてみる。
Aspectを実装しない場合は、全てのメソッドに処理を追加し、確認が終わったら削除しなければならない。
Aspectを実装することで、「全てのメソッドに処理を追加する」という手間を省くことができるのと、「処理を消し忘れる」可能性を無くすことができる。
![AOPメリット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710642/df323e91-384a-3bb5-9b89-36c7813149bf.png)



## 参考文献
- [Spring解体新書第2版](https://amzn.asia/d/5kCJXRs)
- [Spring Framework超入門 優しくわかるWebアプリ開発](https://amzn.asia/d/6S4VXOg)