Spring Frameworkのアノテーションとプロジェクト構造

2022-04-11

Spring Frameworkは、Java言語のWebアプリケーションフレームワークのデファクトスタンダードです。
非常に便利なのですが、アノテーションの種類が多く混乱しがちです。
この記事ではアノテーションの一覧と機能概要、プロジェクトでの利用例をご紹介します。

アノテーション

Core系

アノテーション 付与箇所 説明
@Configuration クラス Java Based Configurationクラスとなる。Bean 定義クラスとして @Bean メソッドなどを宣言。
@ComponentScan クラス @Configuration 付与されたJava Based Configurationクラスに付与し、コンポーネントスキャンを有効化。
@Bean メソッド @Configuration 付与されたJava Based Configurationクラスのインスタンス化メソッドに付与。
@Component クラス DIコンテナにbeanとして登録するクラスへ付与。
@Service クラス @Component と同じだが、明確にService層示す際に利用。
@Repository クラス @Component と同じだが、明確にPersistence層(DAO等のDBアクセスを行うクラス)示す際に利用。
@Controller クラス @Component と同じだが、明確にSpringMVCでControllerの役割となるクラスに利用。
@Scope クラス beanのスコープを設定。
@Transactional クラス、メソッド トランザクション境界を設定。
@Autowired メソッド、フィールド フィールドの型(インターフェース)の実装クラスのbeanを自動的にインジェクション。
@Qualifier メソッド、フィールド @Autowired と併用し、bean名を指定したい場合に使用。
@Value フィールド application.yaml などで指定した値を代入。
@Required メソッド Setterメソッドに付与し、インジェクションが必須であることを示す。

Beanのスコープ

スコープ 説明
singleton (Default) ApplicationContext に 1 つインスタンス化。
prototype Bean 取得毎にインスタンス化。スレッドアンセーフの場合に利用。
request HTTP リクエスト毎にインスタンス化。
session HTTPセッション単位でインスタンス化。
application サーブレットのコンテキスト単位でインスタンス化。warの単位なイメージ。
websocket WebSocketのライフサイクル単位でインスタンス化。
custom 上記以外の独自カスタムスコープ。

SpringMVC系

アノテーション 付与箇所 説明
@Controller クラス MVCコントローラ。
@RestController クラス REST用コントローラ。 @Controller + @ResponseBody と同じ。
@RequestMapping クラス、メソッド URI(value)、HTTPメソッド(method)、HTTPヘッダ(headers)、リクエストパラメータ(params)などでコントローラへのルーティングを設定。
@RequestParam メソッド URLのクエリパラメータをメソッド引数に注入。
@PathVariable メソッド URLのパスパラメータをメソッド引数に注入。
@RequestHeader メソッド リクエストヘッダをメソッド引数に注入。
@RequestBody メソッド リクエストボディをメソッド引数に注入。
@ResponseBody メソッド return するオブジェクトをHTTPレスポンスボディに変換。
@ResponseStatus メソッド HTTPレスポンスステータスを指定。
@ExceptionHandler メソッド クラス内で発生した例外を処理するメソッドに付与。
@CookieValue メソッド 特定の Cookie を処理するメソッドに付与。
@InitBinder メソッド これを付与したメソッド用意すると、バインド処理が行われる前にこのメソッドが呼び出され、デフォルトの動作をカスタマイズすることができる。
@ModelAttribute メソッド これが付与されたメソッドの返り値は、自動でModelに追加される。

SpringBoot系

アノテーション 付与箇所 説明
@SpringBootApplication クラス @Configuration@EnableAutoConfiguration@ComponentScan をまとめたもの。SpringBootアプリケーション起動クラスに付与する。
@EnableAutoConfiguration クラス SpringBoot の自動構成メカニズムを有効化。

Test系

アノテーション 付与箇所 説明
@RunWith(SpringRunner.class) クラス Spring BootでJUnitテストするときはコレをつける。
@SpringBootTest クラス SpringのJava/XML Based Configurationなどの設定を読み込んでくれる。
@AutoConfigureMockMvc メソッド コントローラ層のモック( MockMvc )を作成でき、これでコントローラのJUnitテストが可能になる。
@WebMvcTest(HelloController.class) クラス 上記に加えてコントローラクラスを指定することもできる。
@MockBean フィールド コントローラ内でDIされるモジュールのモック(Mockito)を作成できる。

プロジェクト構造と設定

以下の CleanArchitecture 風なプロジェクト構成を前提に記載します。

  • src/main/java/com/pepese/sample/Application.java : SpringBoot 起動クラス
  • src/main/java/com/pepese/sample/config/ : Java Based Configuration クラス
  • src/main/java/com/pepese/sample/adapter/ : コントローラとか
  • src/main/java/com/pepese/sample/domain/ : ドメインとなる Bean クラス
  • src/main/java/com/pepese/sample/infrastructure/ : リポジトリとか
  • src/main/java/com/pepese/sample/usecase/ : ユースケースとなる Service クラス
  • src/main/resources/logback.xml : ログ設定ファイル

Java Based Configuration と XML Based Configuration

Spring Framework の設定には以下の 2 種類あります。

  • Java Based Configuration
  • XML Based Configuration

もはや前者しか使わないと思われますので、前者に限定して記載します。

  • Spring設定クラス( src/main/java/com/pepese/sample/config/AppConfig.java に配置)
    • DIやAOPなどの設定
    • @Configuration アノテーションを付与
  • SpringMVC設定クラス( src/main/java/com/pepese/sample/config/WebMvcConfig.java に配置)
    • コンテンツネゴシエーションなどSpring MVCのDispatcherServletに関する設定
    • WebMvcConfigurer を継承
      • Spring4 -> 5、SpringBoot1 -> 2 にかけて WebMvcConfigurerAdapter が非推奨となった
    • @Configuration アノテーションを付与すること
      • SpringBootの場合、 @EnableWebMvc を付与する必要はない
      • SpringBootを利用しないSpring MVCアプリケーションを作成する場合には付与する
  • SpringSecurity設定クラス( src/main/java/com/pepese/sample/config/WebSecurityConfig.java に配置)
    • @Configuration@EnableWebSecurity アノテーションを付与
    • WebSecurityConfigurerAdapter を継承
    • configure メソッドなどをオーバーライドして利用
  • SpringSession設定クラス( src/main/java/com/pepese/sample/config/SessionConfig.java に配置)
    • @Configuration@EnableRedisHttpSession アノテーションを付与
    • ConnectionFactory などを生成するメソッドを実装して利用

ロガー

インターフェースに SLF4J 、実装に Logback を利用します。
SpringBoot の場合は依存に含まれているため、特に POM への追加は必要ありません。
LoggerFactory に「クラス」or「名前」を指定することで取得できますが、基本は「クラス」になります。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggertTest {
    // クラス
    private static final Logger log = LoggerFactory.getLogger(LoggerTest.class);
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggertTest {
    // 名前
    private static final Logger log = LoggerFactory.getLogger("MyLogger.test");
}

Lombok の @Slf4j アノテーションをクラスに付与すれば log というフィールドで利用可能になります。

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LoggertTest {
}

ログメッセージに {} を記述すると プレースフォルダー として利用できます。

int num1 = 1234;
int num2 = 5678;
log.debug("この数値は{}と{}です。", num1, num2);
// 20:00:33 DEBUG - この数値は1234と5678です。

Filter などで MDC に項目を追加できます。

import org.slf4j.MDC;
import org.springframework.web.filter.OncePerRequestFilter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LoggingFilter extends OncePerRequestFilter {
    
  public LoggingFilter() {
    super();
  }

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    String httpmethod = request.getMethod();
    MDC.put("httpMethod", httpmethod); // HTTPメソッドをログに追加
    try {
      filterChain.doFilter(request, response);
    } finally {
    }
  }
}

Logback の設定ファイルは src/main/resources/logback.xml です。

おすすめ書籍

おすすめ記事