SpringのDIとLombokはとても相性がいいなぁと今更になって思いました。
Lombokがある時とない時でどう違うの?というのはこれから説明していきたいと思います!
## この記事でわかること
- SpringのDIとLombokはなぜ相性が良いのか
- Lombokがある時とない時のソースコード
この記事はDIの詳細説明はしませんのでご了承下さい🙇♂️
ちなみにLombokとは・・・
こちらの記事でまとめているので、まだLombokを知らないJavaエンジニアは是非覚えましょう!
気づきを得た経緯
タイトルのような気づきを得たキッカケなのですが、以前Springのハンズオン研修があり、そこで曖昧な理解になっていたDIについて復習できました。
ハンズオンのなかで、DIコンテナに登録されたインスタンスをインジェクションする方法は3つあると伺いました。
- コンストラクタインジェクション
- フィールドインジェクション
- セッターインジェクション
このなかで、推奨されている方法がコンストラクタインジェクションなんですね。(final化できるためフィールドのライフサイクル中に値が変更されない)
例えば、以下のようなサービス実装クラスがあった場合
@Service
public class ServiceImpl implements Service {
// 名前を返却するメソッド
public String name() {
return "hoge";
}
}
サービスクラスに@Serviceを付与することでコンポーネントスキャン(DIコンテナに自動登録する機能)され、他のクラスでインスタンスをインジェクション(注入)できるようになります。
このサービスクラスをDemoControllerで利用する場合、コンストラクタインジェクションだと以下のようなコードになります。
@Controller
@RequestMapping("/")
public class Controller {
// フィールド
private final Service service;
// コンストラクタ
public Controller(Service service) {
this.service = service;
}
}
コンストラクタインジェクションは、コンストラクタに@Autowiredを付与する必要がありますが、コンストラクタが一つの場合は@Autowiredを省略可能です!
なるほどね、コンストラクタ必要なのね。という理解でいました。
しかし、実務に戻ってコンストラクタインジェクションしているソースコード(例は以下)を確認してみたら、コンストラクタがないじゃありませんか!?
@Controller
@RequestMapping("/")
@RequiredArgsConstructor
public class Controller {
private final Service service;
}
これは一体どういうことだ、コンストラクタが必要なんじゃないのか・・と混乱しました。
ですが、よくよく考えたら何のことはない、「@RequiredArgsConstructor」というアノテーションがコンストラクタ生成を請け負ってくれていたんですね~
「@RequiredArgsConstructor」はSpringの機能ではなく、Lombokというライブラリの機能になります。
SpringのDIでクラス間の結びつきを密にするのを防げますが、必ず記述しなければならないコード(ボイラープレートコード)が発生してしまいます。そこをLombokと融合することで、ボイラープレートコードも書かずに済みます。
とても相性バッチリな組み合わせということに気がつきました!!
探せば、他にもLombokと相性が良いJava/Springの機能ありそうだなぁ・・・
何かご存知の方いらっしゃったら是非教えてください!