Springアノテーションについての整理

# 導入
Springにはさまざまなアノテーションという機能が存在しています。
今回はこのアノテーションについて触れていきます。

# アノテーションとは
実行環境やコンパイラに対して、そのプログラムの機能がどういうものかを伝えるために利用されるものです。
似たものとしてJavaDocがあります。JavaDocコメントは開発者、つまり人間に対して、プログラムの機能を伝えるためのものです。アノテーションとは、機能を伝える「対象」が異なります。

アノテーションの仕組みは、Spring内でアノテーションを識別して**IoC(Inversion of Control, DI)コンテナにコンポーネントを自動登録**して**必要になったら呼び出す**ことができるというものになっています。

# アノテーションの種類
## 主なアノテーション
### `@Autowired`
指定したクラスに対してDIを行うためのアノテーション
Component系のアノテーションでBean化されたクラスを呼び出す際に利用されます。
applecationConfig.ymlを利用することでAutowiredを使わずにDIすることが可能です。
### `@Conponent`
インスタンス化したいクラスに付与されます。
DIコンテナにBeanとして登録され、Autowiredで利用可能になります。
### `@Controller`
`@Conponent`を継承したアノテーションの1つ。
クライアントとのデータ入出力を制御するクラスに付与されます。
コントローラークラスに付与されます。
### `@Service`
`@Conponent`を継承したアノテーションの1つ。
業務ロジックを保持するクラスに対して付与されます。
サービスクラスに付与されます。
### `@Repository`
`@Conponent`を継承したアノテーションの1つ。
データベースとのやりとりを行うクラスに対して付与されます。
リポジトリークラスに付与されます。
### `@Scope`
対象のライフサイクルを指定することができるアノテーション。
設定できるのは以下の項目です。
- singleton
    - デフォルト値。
    - Spring起動時にインスタンスを1つだけ生成し、そのインスタンスを共有して使用します。
- prototype
    - Beanを取得する度に、毎回インスタンスを生成します。
- session
    - HTTPのセッションごとにインスタンスを生成します。
    - Webアプリケーションにおいて利用されます。
- request
    - HTTPのリクエストごとにインスタンスを生成します。
    - Webアプリケーションにおいて利用されます。
- application
    - サーブレットのコンテキストごとにインスタンスを生成します。
    - Webアプリケーションにおいて利用されます。
- globalSession
    - ポートレット環境におけるGrobalSessionごとにインスタンスを生成します。
    - ポートレットに対応したWebアプリケーションにおいて利用されます。
- カスタムスコープ
    - 独自に定義したルールによりBeanのインスタンスを生成することができます。
### `@Primary`
他のクラスよりも優先的にDIしたいクラスに付与するアノテーション。
### `@Configuration`
アノテーションを使ってDIコンテナへのBean登録する際の処理が複雑な場合に利用されます。
Bean生成用クラスであるJavaConfigに対して付与されます。
### `@Bean`
`@￰Configuration`が付与されたJavaConfig内でインスタンスを生成するメソッドに付与されます。
## コントローラで使用されるアノテーション
### `@RestController`
APIコントローラに付与するアノテーション。
設定したメソッドの戻り値がそのままHTTPのレスポンスボディになります。
### `@￰RequestMapping`
コントローラに付与することで、リクエスト URL に対してどのメソッドの処理を実行するかを設定することができます。
- method属性：GET/POSTといったHTTPリクエストメソッドを設定できる。
- value属性：そのクラス・メソッドで処理するURLのパスを設定できる。
### `@￰GetMapping`
RequestMappingのmethod属性がGETの場合と同じもの。
### `@￰PostMapping`
RequestMappingのmethod属性がPOSTの場合と同じもの。
### `@￰RequestParam`
メソッドの引数に対して付与するアノテーション。
クエリパラメータや、リクエストボディに含まれるパラメータを取得することができます。
- name属性・value属性：リクエストパラメータを指定できる。nameとvalueの役割に違いはありません。
- required属性：パラメータの有無を任意にする場合、falseを指定する。(デフォルトはtrueです)
- defaultValue属性：パラメータがなかった際に使用するデフォルト値を指定します。
### `@￰PathVariable`
URLに含まれる動的なパラメータを受け取るアノテーション。
            
```java
// "http://localhost:8080/sample/tanaka" でアクセスすると、nameには「tanaka」が設定される
@GetMapping(value = "/sample/{name}")
public String sample(@PathVariable("name") String name) {
  return name;
}
```
            
### `@ControllerAdvice`
クラスに付与することで全てのControllerで共有するメソッドを用意することができるアノテーション。
例外処理の共通化などに利用されます。
共有するメソッドには以下のアノテーションを付与します。
#### `@￰ExceptionHandler`
メソッドに付与することで例外処理を実装できるアノテーション。
このアノテーションの引数に指定したクラスが例外処理用のクラスになります。

## サービスで使用されるアノテーション
### `@￰Transactional`
DBを更新する際にトランザクションを管理・制御(例外が起こった時に自動でロールバック)することを設定するためのアノテーション。
- 非検査例外（RuntimeException）やそのサブクラスが発生した場合にロールバック処理が実行されます。
- 検査例外（ExceptionやそのサブクラスでRuntimeException以外）が発生した場合には、ロールバックされずコミットが実行されます。
## リポジトリ・データアクセスで使用されるアノテーション
### `@Data`
クラスに付与し、全フィールドに対してgetter/setterでアクセス可能にするアノテーション。
equals()メソッドやtoString()メソッド、hasCode()メソッドを自動で生成してくれる。
### `@Entity`
DBのテーブルとマッピングするエンティティクラスであることを示すアノテーション。
### `@Table`
エンティティに対応するテーブル名を設定するためのアノテーション。
### `@Id`
主キーを指定するアノテーション。複合主キーを指定する場合は、`@EmbeddedId`を使用します。
### `@Query`
このアノテーションの引数に記述されたSQLを実行できるメソッドを設定するためのアノテーション。

```java
// 例
@Repository
public interface TestEntityRepository extends JpaRepository<TestEntity, Integer> {
    @Query(value = "SELECT test1 FROM test_table WHERE test_id = :test_id ", nativeQuery = true)
    List sampleMethod(@Param("test_id") Integer test_id;
}

// 呼び出すクラス側
@Autowired
TestEntityRepository testEntityRepository;
// (省略)
List result = testEntityRepository.sampleMethod(1);
```