Spring Boot でカスタム validator に injection する
はじめに
Spring Boot で JPA Validator にインジェクションしようとしたけどできなかった、という話を何度か聞いてその度に調べていたので、次回に備えてまとめておきます。 サンプルコードはこちら:
解説
Spring Boot で JPA Validator を利用するのは、典型的には
-
Sprng MVC でハンドラメソッドにアノテーションを付与する
-
永続化時のバリデーション (一般的な JPA Validation の利用方法)
の 2 つのタイミングがあるのかなと思っています。
前者は次のような感じのものです:
|
|
こちらは、 Spring Framework のリファレンス 3.7.2. Configuring a Bean Validation Provider に説明があり、この設定を行うことでカスタム validator でも @Autowired が利用できるようになります。
ちなみに Spring Boot では自動設定されます(ValidationAutoConfiguration)ので明示的なコンフィグレーションは不要です。
よく困るのは後者です。エンティティにアノテーションを付与して、永続化時に検証するものです:
|
|
こちらは自動設定されないので明示的なコンフィグレーションが必要になります。 次のような設定を行います:
|
|
この設定を行うことで、 JPA フレームワークが用いる validator インスタンスの生成が Spring Framework に委譲され、 Spring Bean として管理されることになります。 そのため @Autowired も利用できるようになります。
参考:
- @AutowiredでインジェクトしたUserServiceがnullになってしまう - スタック・オーバーフロー
余談
この検証をしていて気づいたのですが、 validator インスタンスは必要に応じて生成されるんですね。
通常の @Component を付与した Spring Bean は(特に設定しないと)singleton なので 1 つしか生成されないのですが、そうすると不都合あるよな…(validator が状態を持っているので並行して validation できない)とか思っていたのですが、ちゃんとチェックするタイミングごと(context ごと、というのが正確なのかな?)にインスタンス生成されていますね。