SpringのDIとAOPについてまとめる。

# Spring DIとAOPに関してまとめ

だいぶ前に書いて公開を忘れてたやつを公開。

## この記事は
Javaのアプリケーションフレームワークである、Springを用いて開発をする機会が公私ともにありました。
Springを開発をやっていくうえで、DIやAOPなどの概念はなんとなく把握していましたが、いざ説明を求められるとしどろもどろになってしまうこと多々があり、
今後、このフレームワークをきちんと使っていくためにも、ここで上記2つの概要やメリットを記事としてまとめることで理解を深めようと思って記事を書きました。

### 書くこと
* Spring Frameworkとは
* DIとは
* AOPとは

###書かないこと
ここでは、あくまでDIとAOPの考え方やメリットをまとめるものであり、実装方法等を詳細に記述しません。


## 想定読者
* Spring Framework(Bootを含む)を用いて簡単なWebアプリを作ったことがある人
* DI、AOPについてなんとなく知っているが説明を求められると「あばばばば」ってなる人

## Spring Frameworkとは
### 概要
そもそもSpring Frameworkとは何でしょうか。
[公式HP](https://spring.io/projects/spring-framework)ではSpring Frameworkについて、以下のようなことが書かれています。

>The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.

雑に訳すと

> Spring FrameworkはモダンなJavaベースのエンタープライズアプリケーションに対して包括的プログラミングや構造化されたモデルを提供します。また、どのようなプラットフォームでも動作します。

Springはエンタープライズ向けのJavaアプリケーション開発Frameworkです。
Spring　Frameworkの開発当初は軽量フレームワークとして普及していました。しかし、Springは古いインフラ環境を切り捨てることなく開発を進めていきます。そうして、10年以上の長い月日の中で重厚なFrameworkとなっていったようです。

### 代表的なプロジェクト
Springには複数のプロジェクトが存在します。代表的なものには以下のようなものがあります。

* Spring MVC
  * Webアプリケーションを開発するためのFrameworkであり、MVCアーキテクチャを採用している。
* Spring Security
  * Springベースのアプリケーションに対して、認証、認可の仕組みを容易に実現するFrameworkです。Basic認証やLDAP認証、Open ID等の様々な認証に対応している。また、独自の認証方式の実装も可能です。
* Spring Data
  * Spring RDBやNoSQLなど様々なデータストアへのアクセスを容易にするFrameworkです。`Spring Data Commons`、`Spring Data JPA`複数のサブプロジェクトで構成されます。
* Spring Batch
  * バッチアプリケーション向けのFramework、大量のデータ処理に必要な共通機能を提供しています。
* Spring Boot
  * Spring Frameworkのconfigfile群をあらかじめ用意しておき、Spring アプリケーション開発を容易にすることを目的としたSpringプロジェクトです。

###DIとAOP
Springでコアとなる設計思想にDIとAOPと呼ばれるものがあります。Springではこれらの設計思想に基づいたプログラミングを行うことになります。
事項からそれらについてまとめます。

## DI（Dependancy Injection）
DI(Dのependency Injection)は日本語で`依存性の注入`と約されます。一般的なアプリケーションでは、1つの処理を行うために複数のモジュールを組み合わせて実現することが多くあります。そのモジュールには以下のようなものが挙げられます。

*　データベースアクセスを担当するモジュール
*　共通的な機能を切り出したモジュール

DIはこれらような複数のモジュールを組み合わせて、1つの処理を行う場合に力を発揮します。
DIそのものはSpring　Framework特有の考え方ではなく　ソフトウェアデザインパターンの一つで、「Inversion　of Control Principle(制御の反転の原則)」を実現します。**制御の反転**とは伝統的な手続き型の言語に比べて制御の方向が反転していることからそう呼ばれます。

![s_手続型.png](https://qiita-image-store.s3.amazonaws.com/0/202545/bf4129e5-4696-88bc-c6bd-7c56c0c6035e.png)



上の図で手続き型は`クラスA`がインスタンスする際に、`クラスB`がインスタンス化されます。そのため制御の方向は`A→B`となります。
ここで、何らかの方法を用いて、`クラスA`依存する`クラスB`のインスタンスを注入するように処理を変更します。

![s_DI.png](https://qiita-image-store.s3.amazonaws.com/0/202545/628bd193-3ea0-a456-476f-a2d57f54db1d.png)


この場合では、`クラスB`を`クラスA`に注入するため、制御の方向が`B→A`となります。
このように制御の方向を反転させ、`クラスA`では`クラスB`を`インターフェースB`で受け取るような実装にしてあげることによって、`クラスA`は`クラスB`の実態として何が注入されるかを気にせずにすみ、疎結合となります。`インターフェースB`を継承しているオブジェクトであれば注入が可能となるからです。
SpringではIoCコンテナと呼ばれるコンテナを利用し、この制御の反転を実現しています。

IoCコンテナではインスタンスはBeanと呼ばれます。
IoCコンテナを用いることで、今まで直接インスタンスを生成していたのに対して、インスタンスの注入をIocコンテナに任せることができます。

![s_DIコンテナ.png](https://qiita-image-store.s3.amazonaws.com/0/202545/f899a841-477f-2e89-49e6-c3d5314db4c2.png)

###DIコンテナのメリット
SpringのようにインスタンスをDIコンテナから注入する事により、以下のようなメリットがあります。

*　インスタンスのスコープやライフライクルを制御することができる。
*　共通の機能を組み込むことが可能となる。
*　コンポーネント間が疎結合になることによってモックの差し込みなどが容易にでき、単体テストを行いやすくなる。

##　AOP（Aspect Oriented Programing）
### 横断的な関心事とAOP
アプリケーションを実装する際に、`ロギング処理`や`キャッシュ処理`などアプリケーションの本質的な処理である業務ロジックとは関係のない処理があります。これらの処理をアプリケーションに直接記述すると、ログのフォーマットが変更されたなどの際にすべてをコードを手作業で変更するようにしなくてはなりません。変更に弱い、不整合を起こしやすいシステムとなってしまします。
上記のような複数のモジュールに点在する同一処理のことを「横断的な関心事」と呼びます。この横断的関心事を一箇所にまとめることを「横断的な関心事を分離」と呼び、これを中心に考えて設計、実装を行うことをAOP(アスペクト指向プログラミング)といいます。


ここで、AOPを行う上での用語を以下にまとめます。

|用語|説明|
|:-:|:-:|
|Aspect|横断的な関事心。「ロギング処理」や「キャッシュ処理」等のモジュールの関心事がAspectにあたる。|
|Join Point|横断的な関心事のモジュールを実行することが可能なポイント。AOPライブラリーによってポイントの場所が違う。|
|Advice|Aspectのコードのこと。Springでは`Around`、`Before`、<br>`After`等複数の種類が存在する。|
|Pointcut|`Advice`と`Join point`の関係性を表す式の集合体。|
|Weaving|アプリケーションの該当ポイントにAspectを入れ込む処理のこと。Spring AOPでは実行時に行なう。|
|Target|Waving処理によって、フローが変更されるオブジェクトのことを言います。単に、`Adviced`オブジェクトとも呼ばれる。|

#####Adviceの種類
`Advice`は`Join Point`に対して、どのタイミングでその処理が実行されるかによって複数の種類があります。

|Advice|説明|
|:-:|:-:|
|Before|Join Pointの前に実行される。|
|After Returning|join Pointにおける処理が正常終了した後に実行される。|
|After Throwing|Join Pointで例外がスローされた後に実行される。|
|After|Join Pointの後に例外をスローした場合でも、正常終了した場合でも実行される。|
|Around|Join Pointの前後で実行される。|


###SpringのAOP
Springでは、`AspectJ`と呼ばれるフレームワークを用いてAOPを実現しています。
また、DIコンテナ内の`Bean`を`Target`とし`Advice`を差し込むことができます。

DIコンテナからBeanを取り出す際にJava Proxyを使い、`Target`のBeanをラップすることで、`Weaving`を行います。

##　終わりに
まとめてみると、やはりというか理解していないことがたくさんありました。


##　参考文献
-　[Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発](https://www.amazon.co.jp/Spring%E5%BE%B9%E5%BA%95%E5%85%A5%E9%96%80-Spring-Framework%E3%81%AB%E3%82%88%E3%82%8BJava%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BENTT%E3%83%87%E3%83%BC%E3%82%BF/dp/4798142476/ref=sr_1_1?adgrpid=52706263349&gclid=CjwKCAjwza_mBRBTEiwASDWVvm4Z3GbQRD_ZxoQUtN7RpTbLxzRc5YfCNcAlD7KTw3LYYFQcK9MgRRoCqHwQAvD_BwE&hvadid=338539117825&hvdev=c&hvlocphy=1009524&hvnetw=g&hvpos=1t1&hvqmt=e&hvrand=7422956267613613497&hvtargid=kwd-332386918940&hydadcr=27263_11561109&jp-ad-ap=0&keywords=spring%E5%BE%B9%E5%BA%95%E5%85%A5%E9%96%80&qid=1556937603&s=gateway&sr=8-1)