Java Spring Bootと関連ライブラリのアノテーションチートシート（まとめ一覧表あり）


PHP専門で8年SEをやっていたある日、Javaを業務で利用する機会があり勉強をはじめました。
そこでJavaで有名なフレームワークSpring Bootを使ったのですが、**Spring Bootにはたくさんのアノテーションがあり、初学者である自分は混乱してしまいました。**

アノテーションをまとめているチートシートを調べてみたら無かったので、勉強も兼ねていっそ自分で作ってしまおうと思った次第です。

以降、チートシートらしく読みやすくするべく、箇条書きの気軽さを残しつつ

- **簡単な説明を付けて**
- **利用頻度が多いものは説明を多めに**
- **混合しやすい似ているものは比較して**

で、記述していきます。
Java標準のもの、Spring Boot、Spring Security、Spring MVC、Lombokなど複数のライブラリにまたがってアノテーションを紹介します。


記事の最後には **アルファベット順に並べ一言の説明をつけた一覧も用意しています。**

# 【全体を構成するもの】

### @￰SpringBootApplication

SpringBootアプリケーションを作る際に必須のアノテーション。
これを設定することでアプリケーションの自動設定、コンポーネントスキャン、Bean定義をすべて有効になる。

実際には以下の3つのアノテーションを設定しているのと同等。

- `@Configuration`：Javaベースの設定クラスであることを宣言する。 `@Bean` 定義などに使える（後でまた登場します）
- `@EnableAutoConfiguration`：Spring Bootの「自動設定」を有効化。依存関係に応じた設定を自動適用する
- `@ComponentScan`：現在のパッケージ以下を自動でスキャンし `@Component`,`@Service`,`@Controller`,`@Repository`などを登録する


逆にSpringBootの自動構成を無効化して手動でMVC設定したい場合 `@EnableWebMvc` というアノテーションがある。

# 【DIに関するもの】

### @￰Override

JavaSpringなどがなくても使えるJava標準のアノテーション。
親クラスやインターフェースのメソッドをオーバーライド（再定義）していることをコンパイラに教える。

```java
public class Fruits {
    public void color() {
        System.out.println("無色");
    }
}

public class Lemon extends Fruits {
    @Override
    public void color() {
        System.out.println("黄色");
    }
}
```


### @￰Autowired

**対象：クラスのフィールド**

記述するとクラス内で「New」をする必要がなくなる。
使いたい他のクラスをインスタンス化して変数に設定してくれる。

使い方は以下の3つの方法がある（ **結論：コンストラクタインジェクション** が推奨）

#### ①フィールドインジェクションでの利用

```java
public class HogeController {
    @Autowired
    private HugaService service;
    // 以降serviceオブジェクトが利用可
    ...
}
```

#### ②セッターインジェクションでの利用

```java
public class HogeController {
    private HugaService service;
    @Autowired
    public setService(HugaService service) {
        this.service = service;
    }
    // 以降serviceオブジェクトが利用可
...
}
```

#### ③コンストラクタインジェクションでの利用

```java
public class HogeController {
    private final HugaService service;
    @Autowired
    public HogeController(HugaService service) {
        this.service = service;
    }
    // 以降serviceオブジェクトが利用可
...
}
```

#### コンストラクタインジェクションでの利用（応用）

コンストラクタが1つの場合は `@Autowired` アノテーションを省略可能
また **Lombok** の `@RequiredArgsConstructor` アノテーションをつけるとコンストラクタの記述自体を省略可能

(※ `@RequiredArgsConstructor` は後でまた登場しますが大事なアノテーションです）

```java
@RequiredArgsConstructor
public class HogeController {
    private final HugaService service;
    // 以降serviceオブジェクトが利用可
...
}
```

### @￰Component

**対象：クラス**

**全4種類** ある **インスタンス化したいクラス** に付与するアノテーションのうちの1つで、
もっとも基本的、特定の役割を持たない汎用的なもの。
この後登場する `@Autowired` を使いたいクラスを登録しておくイメージで、
これらをつけるとBeanとして定義される。

```java
@Component
public class Utility {
    public String format(String input) { ... }
}
```

### @￰Controller

**対象：クラス**

同じく**インスタンス化したいクラス** に付与するアノテーション。
HTTPリクエストを受け取るクラスにつける。

```java
@Controller
public class HelloController {
	@GetMapping("/hello")
    public String handle(Model model) { ... }
}
```

### @￰Service

**対象：クラス**

同じく**インスタンス化したいクラス** に付与するアノテーション。
ビジネスロジックを担当するクラスにつける。

```java
@Service
public class UserService {
    public void registerUser(User user) { ... }
}
```

### @￰Repository

**対象：クラス**

同じく**インスタンス化したいクラス** に付与するアノテーション。
データベースとのやりとり（DAO）をするクラスにつける。

```java
@Repository
public class UserRepository {
    public User findById(Long id) { ... }
}
```

##### 4つのアノテーションのまとめ


| アノテーション       | 主な用途               | よく使うクラス        |
| ------------- | ------------------ | -------------- |
| `@Component`  | 汎用コンポーネント（共通処理など）  | ユーティリティ、共通ヘルパー |
| `@Repository` | データアクセス層（DB関連）     | DAO、リポジトリクラス   |
| `@Service`    | ビジネスロジック層（サービス処理）  | サービスクラス        |
| `@Controller` | プレゼンテーション層（Web受け口） | Webのコントローラ     |


**レイヤー構造イメージ**

```
Controller  ← @Controller
     ↓
Service Layer ← @Service
     ↓
Repository Layer ← @Repository
     ↓
DB / 外部API
```


### @￰Configuration / @￰Bean

**対象：クラス、メソッド**

これまで登場した他のアノテーションを使うのが難しい場合にはJavaConfigという **Beanを生成するクラス** を使うのだが、そのクラスに付けるアノテーション。
そのクラス内でインスタンスを作成するメソッドには `@Bean` アノテーションがつく。

```java
@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}
```

### @￰Scope("XXXXXX")

**対象：クラス**

()の中に決められたルールを指定することでインスタンスを生成（＝破棄）するタイミングを指定することができる。

```java
@Bean
@Scope("prototype")
public MyService myService() {
    return new MyService();
}
```

代表的なものは以下
- `singleton`：デフォルトでこれ、コンテナ内で1つだけインスタンスを共有
- `prototype`：インスタンスが必要なたびに毎回新しいものを生成
- `request`：HTTPリクエストごとに新しいインスタンスを生成


### @￰Primary

**対象：クラス**

例えば同じインターフェースをimplementsしている2つのクラスがあった場合
依存注入する側（他のクラスを `New` をしているクラス、つまり `@￰Autowired` などを書くクラス）ではどのクラスが注入したいもの（Newしたいもの）かわからない。

その場合 `@Primary` が記述されたクラスが優先だと判断できる。
また `@Qualifier` アノテーションを使うと注入する側でクラスを明示的に選ぶことができる。
（使い方は検索）


# 【Controllerクラスにつけるもの】

### @￰Controller / @￰RestController

**対象：クラス**

つけることでSpring Bootがそのクラスをコントローラだと認識する。
通常は `@Controller` を使うが、JSONやXMLなどを返すWebAPI用のコントローラでは `@￰RestController` を使う。

### @￰RequestMapping

**対象：メソッド**

クライアントからのリクエストに対して動くメソッドを対応させることができる。
この仕組みを **マッピング** という。

```java
    @RequestMapping("/greet_morning")
    public string greetAtMorning() {
        return "Good morning.";
    }

    @RequestMapping("/greet_night")
    public string greetAtNight() {
        return "Good evening.";
    }
```

`@RequestMapping` は属性を利用することでマッピングの条件を指定できる。

```java
@RequestMapping(value="/greet_night", method=RequestMethod.GET, headers="Accept=application/*", params="id=0900")
```

しかし、ただ単にGETとPOSTくらいしか条件を指定しない場合は以下に紹介する `@￰GetMapping` と `@￰PostMapping` を利用すると `method=RequestMethod.GET` の部分を省略することができる。


### @￰GetMapping / @￰PostMapping

**対象：メソッド**

それぞれ `@RequestMapping` のGET用とPOST用のもの。
よって以下の2つは機能的に全く同じ。文字数が減るのでこっちの2つを利用したほうがいいと思う。

```java
@RequestMapping(value="/greet_morning", method=RequestMethod.GET)
@GetMapping(value="/greet_morning")
```

ちなみに `@￰GetMapping` と `@￰PostMapping` でも属性を利用することでマッピングの条件を指定できる。

```java
@GetMapping(value = "/greet_morning", params = "id", produces = "application/json")
```

### @￰RequestParam

**対象：メソッドの引数**

リクエストに含まれるパラメータを取得することができる。
**Webアプリケーション開発ならよく使う。**
先述の `@XXXMapping` 系のアノテーションと組み合わせ使う。

```java
@GetMapping("/greet")
public String greet(@RequestParam String name) {
    return "Hello, " + name;
}
```

他にも色々な属性があるがよく使うのは以下

- `required`：必須かどうか
- `defaultValue`：パラメータが存在しない時のデフォルト値

属性はカンマ区切りで複数記述できる。
**以下の様に属性を複数つけると初学者の可読性は一気に下がるが慣れていきたい。**

以下の例では `/search?q=apple` なら `"apple"` を、
`/search`（パラメータ無し）なら `"all"` を返します。

```java
@GetMapping("/keyword-search")
public String search(@RequestParam(value = "q", required = false, defaultValue = "all") String query) {
    return "検索キーワード：" + query;
}
```
1行が長くなってきたら改行も検討しよう。


### @￰PathVariable

**対象：メソッドの引数**

これも `@￰RequestParam` と同じ様にリクエストに含まれるパラメータを取得するものだが、
こちらはURLのパスそのものから値を取得する。つまり、

- `@￰RequestParam` は `?name=XXX` の部分を取得
- `@￰PathVariable` は `/user/{XXX}` の部分を取得

という違いがある。

同時に利用すると以下のような例になる。
以下では `/users/5/orders?page=2` というURLが想定される。

`{userId}`の部分を `@PathVariable` で取得し、URLの最後の `page=2` を `@RequestParam` で取得している。

```java
@GetMapping("/users/{userId}/orders")
public String getUserOrders (
    @PathVariable Long userId,
    @RequestParam(defaultValue = "1") int page
) {
    return "User ID: " + userId + ", Page: " + page;
}
```


### @￰ModelAttribute / @￰RequestBody

**対象：メソッドの引数**

`@RequestParam`、`@PathVariable`に加えて、この2つもHTTPリクエストからパラメータを取得するものだが、

`@￰ModelAttribute` は **フォーム送信された複数の値をまとめて1つのオブジェクトとして取得ができる。**

```html
<form method="post" action="/register">
  <input name="name" />
  <input name="email" />
</form>
```
このフォームから送られた値が以下で取得される。

```java
@PostMapping("/register")
public String register(@ModelAttribute UserForm form) {
    return "Welcome " + form.getName();
}
```

`@RequestBody` はフォーム送信ではなく **JSONやXMLなどの構造化データをのオブジェクトとして取得する。**
以下のような感じ。

```json
{
  "name": "Taro",
  "email": "taro@example.com"
}
```

```java
@PostMapping("/api/users")
public String createUser(@RequestBody UserDto user) {
    return "Created: " + user.getName();
}
```

よって4つのアノテーションをまとめると以下のような表になる。

|目的|使うアノテーション|
|---|---|
パスから取得するを取りたい|@￰PathVariable
クエリパラメータを使う|@￰RequestParam
フォームデータをまとめてオブジェクト化|@￰ModelAttribute
JSONをオブジェクト化|@￰RequestBody

※コントローラに渡されるリクエストデータの変換・整形・バリデーションをカスタマイズするためには、`@InitBinder`アノテーションをつけたメソッドを用意する。

### @￰ControllerAdvice

**対象：クラス**

**すべてのコントローラに共通の処理** を作りたい時、このアノテーションを用いる。
**例外処理、バリデーションなどを行うクラスでの利用が想定される。**

### @￰ExceptionHandler

**対象：メソッド**

**特定の例外** 発生時に呼び出されるメソッドを定義する。
サービス全体で共通の例外であれば `@ControllerAdvice` アノテーションを使っているクラス内で用いられる。

```java
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleIllegalArg(IllegalArgumentException ex) {
    return ResponseEntity.badRequest().body("不正な引数: " + ex.getMessage());
}
```


# 【Repositoryクラスにつけるもの】

### @￰Data

**対象：クラス**

**Lombok** のアノテーションであり、使うことで **多くのコードの記述を省略できる。**
クラスに設定されたすべてのフィールドに対して必要なgetter/setter、 `toString()` メソッドなどを自動生成してくれる。

```java
public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "'}";
    }
}
```

上記のコードと同じ機能が以下のコードにまで省略される。

```java
import lombok.Data;

@Data
public class Person {
    private String name;
}
```

他にも `equals()` や `hashCode()` も自動で作られる。

Lombokには`@Getter`,`@Setter`,`@ToString`,`@EqualsAndHashCode`,`@RequiredArgsConstructor`など多くの便利なアノテーションがあるが、`@Data`を使うことですべてのアノテーションを省略することができる。
簡単なBeanの作成に向いている。


###  @￰◯◯ArgsConstructor

それぞれコンストラクタの記述を省略してくれるアノテーション。

##### @￰RequiredArgsConstructor

`final`または`@NonNull`が付いたフィールドだけを引数に取るコンストラクタを自動生成する。

```java
@RequiredArgsConstructor
public class User {
    private final String username;
    private final int age;
    private String address;
}
```

以下が自動生成される。

```
public User(String username, int age) {
    this.username = username;
    this.age = age;
}
```

##### @￰NoArgsConstructor

引数なしのデフォルトコンストラクタを自動生成する。

```java
@NoArgsConstructor
public class User {
    private String username;
    private int age;
}
```

以下が自動生成される。

```
public User() {
}
```

##### @￰AllArgsConstructor

すべてのフィールドを引数に取るコンストラクタを自動生成する。

```java
@AllArgsConstructor
public class User {
    private String username;
    private int age;
}
```

```java
public User(String username, int age) {
    this.username = username;
    this.age = age;
}
```


### @￰Entity / @￰Id

**対象：クラス/フィールド値**

`@Entity` アノテーションを使うことでJPA（Java Persistence API）対象であることを示す。（「永続化対象」という呼び方）
つまりは、 **クラス1つとテーブル1つとリンクさせるイメージ。**

同時に `@Id` アノテーションを **いずれかのフィールド値に設定することが必須となる。**
`@Id` を書いたフィールド値が主キーとなる。主キーがないと永続化ができない。

基本的にはテーブル名とクラス名を同じにするが、
テーブル名とクラス名が別の場合は `@Table` アノテーションを使う。

`@Table(name = "users")` のようにして `@Entity` と並べてクラスに記述する。

自動裁判をする際には `@GeneratedValue(strategy = GenerationType.IDENTITY)` を同時に使うことが多い

```java
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private int price;
}
```

### @￰Transient

**対象：フィールド値**

`@Entity` を使ったクラスにおいて、DBに保存しない値を指定するためのアノテーション。
一時的な計算結果などに用いたりする。


### @￰Query / @￰Modifying / @￰Transactional

SQLを書くメソッドには `@Query` アノテーションが必要となる。
また更新（UPDATE）または削除（DELETE）のクエリの場合は `@￰Modifying` のアノテーションも併せて必要となる。

更新・削除の場合トランザクションが必要であるため、さらに併せて `@Transactional` 利用する。

```java
public interface UserRepository extends JpaRepository<User, Long> {

    @Transactional
    @Modifying
    @Query("UPDATE User u SET u.age = :age WHERE u.id = :id")
    int updateAge(@Param("id") Long id, @Param("age") int age);
}
```

### @￰JoinColumn / @￰OneToOne / @￰OneToMany / @￰ManyToOne

**対象：フィールド値**

どれも **リレーション（テーブル間の関連）**  を定義するときに使うアノテーション。
リレーションの説明は割愛するが、記述が簡潔になる、整合性の確保が楽になるなどのメリットがある。

|アノテーション|関係	|意味（片側から見た関係）
|--|--|--
@￰OneToOne	|1対1	|「1人のユーザーに1つのプロフィール」など
@￰OneToMany	|1対多	|「1人のユーザーに複数の投稿」など
@￰OneToMany	|多対1	|「複数の投稿は1人のユーザーに属する」など
@￰JoinColumn	|外部キー指定	|外部キー列（FK）をどのカラムにするか明示する

以下のように書いておけば

```java
@Entity
public class Post {
    @Id
    private Long id;

    private String title;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}
```

リポジトリ層、サービス層では記述が簡単になる。

```java
Post post = postRepository.findById(1).get();
String userName = post.getUser().getName();
// JOIN不要で、投稿ID：1の投稿のユーザー名や名前をuserテーブルから取得できている
```

# 【バリデーションをするもの】

### @￰Validated

**対象：メソッドの引数** もしくは **クラス**

バリデーションをする際に利用するアノテーション。
利用方法が複数あるため、詳しくは割愛し、簡単な例を記載する。

##### メソッドに書く方法

フォームの値をバリデーションするクラスを作成しておく。

```java
@PostMapping("/submit")
public String submitForm(@Validated @ModelAttribute UserForm form) {
    // バリデーション済みの form を使える
    return "OK";
}
```

```java
public class UserForm {
    @NotBlank
    private String name;

    @Email
    private String email;

    // getter/setter省略
}
```

##### クラスに書く方法


```java
@Service
@Validated
public class UserService {
    public void deleteUser(@Min(1) Long id) {
        // idが0や負の数なら例外が発生する
    }
}
```

### バリデーションルール用のアノテーション

他にも多くあるがよく使う一部を紹介。

|アノテーション|説明|
|---|---|
|@￰NotNull	|nullの禁止	|
|@￰NotBlank	|空文字・空白 禁止	|
|@￰Size	|長さ・サイズの範囲	|
|@￰Email	|メールアドレス形式かどうか	|
|@￰Pattern	|正規表現による形式チェック	|


# 【セキュリティ（SpringSecurity）】

### @￰EnableWebSecurity

Spring SecurityのWebセキュリティサポートを有効になり、
認証・認可などのフィルターが適用される。

現在は以下のように `SecurityFilterChain` と併用して使うのが主流となっている。

```java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().permitAll()
            )
            .formLogin(Customizer.withDefaults()); // ログインフォームを有効化

        return http.build();
    }
}

```


### @￰PreAuthorize / @￰PostAuthorize

`@￰PreAuthorize` はメソッドが呼び出される前にアクセス権をチェックし、
`@￰PostAuthorize` はメソッドの実行後にアクセス権をチェックする。



### @￰AuthenticationPrincipal

認証済みのユーザー情報をメソッド引数に注入する。

```java
@GetMapping("/profile")
public String getProfile(@AuthenticationPrincipal UserDetails userDetails) {
    return "ユーザー名: " + userDetails.getUsername();
}
```

# まとめ

|アノテーション|ライブラリ／分類|説明
|---|---|---
|`@AllArgsConstructor`|Lombok|全フィールドを引数に持つコンストラクタを自動生成
|`@AuthenticationPrincipal`|Spring Security|認証済みユーザー情報を取得
|`@Autowired`|Spring Framework|依存性注入 (DI) を行う
|`@Bean`|Spring Framework|SpringコンテナにBean定義を登録
|`@Component`|Spring Framework|汎用のDI対象クラスを定義
|`@Configuration`|Spring Framework|設定クラスであることを明示
|`@Controller`|Spring MVC|Webリクエストを処理するクラスを定義
|`@ControllerAdvice`|Spring MVC|例外処理やバインディング処理の共通化
|`@Data`|Lombok|Getter/Setter, toString などを自動生成
|`@EnableWebSecurity`|Spring Security|Spring Securityの設定を有効化
|`@Entity`|Spring Data JPA|JPAエンティティクラスを定義
|`@ExceptionHandler`|Spring MVC|例外処理メソッドを定義
|`@GetMapping`|Spring MVC|GETリクエストをマッピング
|`@Id`|Spring Data JPA|主キーを表す
|`@JoinColumn`|Spring Data JPA|関連テーブルの結合列を指定
|`@ManyToOne`|Spring Data JPA|多対一のリレーションを定義
|`@ModelAttribute`|Spring MVC|リクエストパラメータをオブジェクトにバインド
|`@Modifying`|Spring Data JPA|変更系のクエリを定義
|`@NoArgsConstructor`|Lombok|引数なしコンストラクタを自動生成
|`@OneToMany`|Spring Data JPA|一対多のリレーションを定義
|`@OneToOne`|Spring Data JPA|一対一のリレーションを定義
|`@Override`|Java標準|メソッドのオーバーライドを明示
|`@PathVariable`|Spring MVC|URLパスの変数部分を取得
|`@PostAuthorize`|Spring Security|メソッド呼び出し後の権限チェック
|`@PostMapping`|Spring MVC|POSTリクエストをマッピング
|`@PreAuthorize`|Spring Security|メソッド呼び出し前の権限チェック
|`@Primary`|Spring Framework|複数候補があるときに優先されるBeanを指定
|`@Query`|Spring Data JPA|独自JPQLクエリを指定
|`@Repository`|Spring Framework|データアクセス層のクラスを定義
|`@RequestBody`|Spring MVC|リクエストのボディをJavaオブジェクトに変換
|`@RequestMapping`|Spring MVC|リクエストをメソッドにマッピング
|`@RequestParam`|Spring MVC|リクエストパラメータを取得
|`@RequiredArgsConstructor`|Lombok|final フィールド用コンストラクタを自動生成
|`@RestController`|Spring MVC|REST API用コントローラ（Controller + ResponseBody）
|`@Scope("XXXXXX")`|Spring Framework|Beanのスコープを定義（例: singleton, prototype）
|`@Service`|Spring Framework|ビジネスロジック層のクラスを定義
|`@SpringBootApplication`|Spring Boot|アプリ全体の設定と自動構成を有効化
|`@Transactional`|Spring Framework / JPA|トランザクション管理を行う
|`@Transient`|Spring Data JPA|永続化対象外のフィールドを定義
|`@Validated`|Spring Framework|バリデーションを有効にする


***

# 参考にさせていただいたリファレンス

- [【Spring Boot】 アノテーションまとめ](https://qiita.com/ist-a-ku/items/c20d67140402634cd5db)
- [Spring Boot解説第18回(基本編：Controllerとは)](https://qiita.com/TEBASAKI/items/267c261db17f178e33eb)
- [Spring Securityよく使用するアノテーション&メソッド](https://qiita.com/JK447/items/4e60948ab5fa1b2b931d)
- [Spring Bootの@ModelAttributeと@RequestBodyの違い](https://qiita.com/blue_islands/items/39d5012f51aaeeb34efb)
- [Lombokが便利だなと感じたので書いてみた](https://qiita.com/supreme0110/items/391505da8f4321736421)