Springアノテーション備忘録～lombokもあるよ～

#タイトル
Spring アノテーション備忘録

#概要
* Spring bootを学習している際に出てきたアノテーションを備忘の為にまとめてみました。
* 各アノテーションについて、調べた内容を自分用に簡単に整理したものとなります。
* Spring boot,lombokなど色々なアノテーションを集めていますので使用の際はご注意ください。
* 例文中におけるpackage宣言、import宣言は省略してあります。

学習中の為、認識違いや説明不足が多々あると思いますので、気づいた方がいましたらご指摘いただけると幸いです。
また、記載のないもので、覚えておくと便利なものをご存知でしたらコメントいただけると~~泣いて~~喜びます。

#目的
* 備忘録
* Spring bootでWebアプリケーションを作成する際によく使いそうなアノテーションの理解を深める

#目次
よく使いそうな場所で分類(※一概に特定のクラスで使用する、使用可能というわけではない)
1. Controller
　1. `@Controller`
　2. `@RequestMapping`
　3. `@ResponseBody`
　4. `@PostMapping`
　5. `@GetMapping`
　6. `@PathVariable`
　7. `@RequestParam`
　8. `@Autowired`
　9. `@Value`
2. Service
　1. `@Service`
　2. `@Transactional`
3. Repository
　1. `@Repository`
4. Component
　1. `@Component`
　2. `@Data`

#1. Controller
画面遷移の制御(リクエストマッピング)とServiceの呼び出しを行う。

##1-1. `@Controller`
###いつ使う？
* Spring MVCにおけるコントローラクラスを定義したいとき。

###説明色々
* コントローラクラスとして扱うコンポーネントであることを示す。 
* コントローラクラスとして扱いたいクラスに対して付与する。

###例文
```java:ExampleController.java
@Controller
public class ExampleController {
	// 中略
}
```

###参考
* [Spring MVCのドキュメント「コントローラを実装する」を読む(1)](http://m12i.hatenablog.com/entry/2014/11/15/150515)


---


##1-2. `@RequestMapping(value="URL")`

###いつ使う？
* クラスまたはメソッドを、URLとマッピングしたいとき。

###説明色々
* valueに設定したURLが指定された時に、アノテーションを付与したクラスかメソッドが呼び出される。
* 戻り値はビューのパスに対応した文字列を指定することで、ビューを返す。[ビュー以外を返したい場合は、1-3. `@ResponseBody`を参照]
* クラスに使用するときはURLのプレフィックス（親パス）に一致させることができる。
* メソッドに使用するときは親パスからの相対パスも指定できる。（絶対パスも可能）

###指定できる属性
* value
URLのパスを指定する。
他に属性が指定されていない場合、属性名は省略が可能<br>
[`@RequestMapping`(value="URL") ⇒ `@RequestMapping`("URL")]
* method
GET、POSTなどのメソッド属性を指定する。<br>[`@RequestMapping`(value="URL" method=RequestMethod.POST)<br>
複数指定するとOR条件になる。<br>[`@RequestMapping`(value="URL" method={RequestMethod.POST,RequestMethod.GET})
* headers

>HTTPのヘッダを指定できます。

らしい。[詳しくは参考:Controllerの処理メソッドとリクエスト（URL等）とのマッピング方法]を参照

* params
>リクエストパラメタを指定できます。
らしい。（詳しくは参考を参照）

###例文
```java:ExampleController.java
@Controller
@RequestMapping(value="/example")
public class ExampleController {

	@RequestMapping("sample") //URLに http://xxxx:xxxx/example/sample が実行されたときに呼ばれる。(相対パス)
	public String sampleMethod() {
		return "example/sample"; //ディレクトリ構成がデフォルトの場合、src/templates/example/sample.htmlを返す
	}
}
```

###参考
* [Controllerの処理メソッドとリクエスト（URL等）とのマッピング方法](https://sites.google.com/site/soracane/home/springnitsuite/spring-mvc/07-controllerno-chu-limesoddotonomappingu-fang-fa)
* [【Spring MVC】@RequestMapping の基本](https://www.shookuro.com/entry/2016/08/21/134349)


---


##1-3. `@ResponseBody`
###いつ使う？
`@RequestMapping`でテンプレートパスに対応したビュー以外を返したいとき。（ページ遷移をせずにリクエストマッピングを行うなど）

###説明色々
* `@RequestMapping`が設定されていて、ビュー以外を返したいメソッドに付与する。

###例文
```java:ExampleController.java
@Controller
@RequestMapping(value="/example")
public class ExampleController {

	@RequestMapping("/sample")
	@ResponseBody
	public String sampleMethod() {
		return "sample"; //"sample"という文字列リテラルが戻る。
	}
}
```

###参考
* [Spring MVCの散歩道■応用の森　Spring-MVC　コントローラの戻り値](https://arimodoki.dip.jp/promenade/hy_spring_cntl_return.html)


---


##1-4.`@PostMapping`
###いつ使う？
* POSTのリクエストをURLとマッピングしたいとき。

###説明色々
* `@RequestMapping`(value="URL", method=RequestMethod.POST)と同義。
* 可読性の向上。

###例文
```java:ExampleController.java
@Controller
@RequestMapping("/example")
public class ExampleController {

	@PostMapping("top")
	public String top() {
		// 中略
	}
}
```

###参考
* [Spring FrameworkのControllerの基本的なアノテーション | 酒と涙とRubyとRailsと](https://morizyun.github.io/java/spring-framework-controller-annotation.html)
---



---


##1-5. `@GetMapping`

###いつ使う？
* GETのリクエストをURLとマッピングしたいとき。

###説明色々
* `@RequestMapping`(value="URL", method=RequestMethod.GET)と同義。
* 可読性の向上。

###例文
```java:ExampleController.java
@Controller
@RequestMapping("/example")
public class ExampleController {

	@GetMapping("top")
	public String top() {
		// 中略
	}
}
```

###参考
* [Spring FrameworkのControllerの基本的なアノテーション | 酒と涙とRubyとRailsと](https://morizyun.github.io/java/spring-framework-controller-annotation.html)


---


##1-6. `@PathVariable`
###いつ使う？
* URLの一部に組み込まれた値を、パラメータ値として取得したいとき。

###説明色々
* URLの一部をパラメータとして取得することができる。
* `@RequestParam`とは似ているが、こちらは直接リクエストのURLに組み込まれている。

###例文
```java:ExampleController.java
@Controller
@RequestMapping("/example")
public class ExampleController {
	
	//http://xxxx:xxxx/example/myPage/12345 の様なリクエストが来たら呼ばれる
	//PostMappingのvalue、userIdがキーとなり、URLの値がバリューとなる
	@PostMapping("myPage/{userId}")
	public String myPage(
		@PathVariable("userId") int argUserId		
	) {
		// 中略
	}	
}
```

###参考
* [Spring Controllerの@PathVariableと@RequestParamの使い分け | Permanent Til](https://permanent-til-me.ssl-netowl.jp/archives/496)
* [Spring MVC コントローラの引数 - Qiita](https://qiita.com/MizoguchiKenji/items/2a041f3a3eb13274e55c)


---


##1-7. `@RequestParam`
###いつ使う？
URLに付与されたパラメータ値を取得したいとき。

###説明色々
* URLに付与されたパラメータ値を取得することができる。
* `@PathVariable`とは似ているが、こちらはリクエストのURLに追加で付与されている。

###例文
```java:ExampleController.java
@Controller
@RequestMapping("/example")
public class ExampleController {
	
	//http://xxxx:xxxx/example/account?userId=12345 の様なリクエストが来たら呼ばれる 
	//userId=12345 のuserIdがキーとなり、12345がバリューとなる
	@PostMapping("account")
	public String top(
		@RequestParam("userId") int argUserId
	) {
		// 中略
	}
}
```
###参考
* [Spring Controllerの@PathVariableと@RequestParamの使い分け | Permanent Til](https://permanent-til-me.ssl-netowl.jp/archives/496)
* [Spring MVC コントローラの引数 - Qiita](https://qiita.com/MizoguchiKenji/items/2a041f3a3eb13274e55c)

---

##1-8.`@Autowired`
###いつ使う？
変数にインスタンスを設定したいときに使用する。(推奨されていないらしい...詳しくはコンストラクタインジェクションで検索)

###説明色々
* 至極簡単に言うとインスタンス変数に付与するとnewしてくれる。（実態は違う）<br>
　　　　　　　↓　詳しくは...　↓<br>

>@Autowired は Spring 管理下のオブジェクトの中から、適切なものを変数にセットするため、インスタンス変数に付けるアノテーションである。
>参考：【Spring】@Autowired と @Component を使用した DI の基本から引用

調べている中でこの説明が一番わかりやすいと感じました。(※Spring管理下のオブジェクトは、コンポーネントとして認識させているもののこと。)

* 同一パッケージ内から自動でDI(Dependency Injection)を行ってくれるので実装先を気にせずインスタンスを操作できる。
* 単純なクラスコンポーネントならインスタンスを自動で作ってくれる。
* インターフェースなら* * 実装先のインスタンスを自動で作ってくれる。* * （実装先が複数ある場合はRunTimeExceptionが発生してしまうようなので注意）
* DIを行いたいフィールドの前に付与する。

###例文
```java:CalcService.java
@Service
public interface CalcService {
	public int add(int x, int y);
}
```
```java:CalcServiceImpl.java
@Service
public class CalcServiceImpl implements CalcService {
	public int add(int x, int y) {
		return x + y;
	}
}
```
```java:ExampleController.java
@Controller
@RequestMapping("/example")
public class ExampleController {
	@Autowired
	CalcService calcService;

	@RequestMapping("calc")
	public String printTotal() {
		int x = 5;
		int y = 20;
		
		calcService.add(x, y);
		//（中略）
		return "example/result"; 
	}
}
```

###参考
* [【Spring】@Autowired と @Component を使用した DI の基本](https://www.shookuro.com/entry/2016/08/09/175801)
* [Spring Boot 5 AutowiredとDI - 暇な日々にスパイスを](http://snona.hatenablog.com/entry/2016/02/16/052923)

---

##1-9. `@Value`
###いつ使う？
* 外部設定値を使用したいとき。

###説明色々
* 外部プロパティファイルに設定した値を代入する。
* 代入を行いたい変数宣言の前に付与する。

###例文
```java:なにかしらのプロパティファイル
sample.sampleId=12345
sample.samplePass=password
```
```java:Sample.java
@Component
public class Sample {
	@Value("${sample.sampleId}")
	private int id;

	@Value("${sample.samplePass}")
	private String password;
}
```
###参考
* [Spring Bootがプロパティファイルを読み込む方法に一同驚愕！！ | Tagbangers Blog](http://blog.tagbangers.co.jp/ja/2019/07/12/how-spring-deals-with-properties)
* [Spring Bootの外部設定値の扱い方を理解する - Qiita](https://qiita.com/kazuki43zoo/items/0ce92fce6d6f3b7bf8eb)
* [【Spring】@Valueアノテーションとは - IT技術総合Wiki | CWiki](https://jpn.itlibra.com/article?id=20560)

---

##2.Service
業務処理（Business Logic）を提供する。

##2-1. `@Service`
###いつ使う？
* Spring MVCにおけるサービスクラスを定義したいとき。

###説明色々
* サービスクラスとして扱うコンポーネントであることを示す。 
* サービスクラスとして扱いたいクラスに対して付与する。

###例文
```java:SampleService.java
@Service
public interface SampleService {
	public void print();
}
```
```java:SampleServiceImpl.java
@Service
public class SampleServiceImpl implements SampleService {
	public void print() {
		System.out.print("Hello.");
	}
}
```

---

##2-2. `@Transactional`
###いつ使う？
* トランザクション処理を行いたいとき。

###説明色々
* 例外が発生したときに、自動でロールバックを行う。（標準ではRuntimeException発生時）
* `@Transactional`(rollbackFor = Exception.class)と記述することでExceptionからその子クラスまでの例外が発生したときにロールバックを行う。
以下、参考から引用

>@Transactionalが動作するための条件
>・DIしているクラスのpublicメソッドであること
>・DIしている別のクラスもしくはフレームワークから直接呼ばれていること

###例文
```

//考え中

```
###参考
* [使い方を間違えると動作しない@Transactionalを動作させる使い方 - Qiita](https://qiita.com/kojiita/items/3115646a6e5adcabc1b6)

---

#Repository
データアクセス層のクラスを提供する。

##3-1. `@Repository`
###いつ使う？
* Spring MVCにおけるリポジトリクラスを定義したいとき。(DAOを含む、DBアクセスを行うクラス。)

###説明色々
* リポジトリクラスとして扱うコンポーネントであることを示す。 
* リポジトリクラスとして扱いたいクラスに対して付与する。

###例文
```java:SampleRepository.java
@Repository
public interface SampleRepository {
	public List<String> search(String keyword);
}
```
```java:SampleRepositoryImpl.java
@Repository
public class SampleRepositoryImpl implements SampleRepository {
	public List<String> search(String keyword) {
		//DB操作処理
	}
}
```
###参考
* [【Spring】@Repositoryアノテーションとは - IT技術総合Wiki | CWiki](https://jpn.itlibra.com/article?id=20536)
* [@Component、@Service、@Repository、@Controllerの違いについて - Qiita](https://qiita.com/KevinFQ/items/abc7369cb07eb4b9ae29)

---

##Component


##4-1. `@Component`
###いつ使う？
* Spring MVCに限らず、Springのコンポーネントとして扱うとき。
* `@Controller`,`@Service`,`@Repository`以外の役割でコンポーネントを使用するとき。（ユーティリティクラスなど）

###説明色々
* SpringのDIコンテナ内のコンポーネントであることを示す。 
* コンポーネントとして扱いたいクラスに付与する。

###例文
```java:Account.java
@Component
public class Account {
	private String id;
	private String name;
	
	//getter,setter略
}
```
###参考
* [Spring - Springフレームワーク@Beanと@componentの違い｜teratail](https://teratail.com/questions/68235)
* [Spring Framework 要点まとめ ～ DIについて - Qiita](https://qiita.com/asksaito/items/2c854065e5803463ebfd)
* [@Component、@Service、@Repository、@Controllerの違いについて - Qiita](https://qiita.com/KevinFQ/items/abc7369cb07eb4b9ae29)

---

##4-2. `@Data`
###いつ使う？
Beanクラスのコード量を削減したいとき。
###説明色々
* lombok（lombok.Data）のアノテーションである。
* 付与することでgette,setterの省略が可能。
* hashCodeメソッドをオーバーライドしてくれる。（インスタンスのハッシュ値を返す）
* toStringメソッドをオーバーライドしてくれる。（インスタンスの文字列表現を返す）
* equalsメソッドをオーバーライドしてくれる。（インスタンスの同値性を判定して返す）
###例文
```java:Account.java
@Component
@Data
public class Account {
	private String accountId;
	private String password;
	private String firstName;
	private String lastName;
	private int age;
	
	//getter,setterの記述は無いが内部で実装されている為使用が可能
}
```

###参考
* [Lombok - @Data - 覚えたら書く](https://blog.y-yuki.net/entry/2016/09/29/000000)
* [劇的にコード量を減らせるLombok | Java好き](https://javazuki.com/articles/lombok-introduction.html)
* [Javaを陰から支えるhashCode、その仕組みと実装方法を基礎から紹介](https://engineer-club.jp/java-hashcode#hashCode)
* [toString()をオーバーライドして自身の情報を親切に伝える - Qiita](https://qiita.com/NagaokaKenichi/items/78015f53979b2545c2e6)

---