エキサイト株式会社メディア事業部エンジニアの佐々木です。Lombok
の@RequiredArgsConstructor
が便利で弊社では多用しているのですが、@Qualifier
を使用したいときに、コンストラクタを書かないといけないのが面倒でした。Lombokのドキュメントを眺めていたところ解決方法があったので、ご紹介します。
DIの登録コード
下記のようにRestClientを複数個設定することは、結構あるかなと思います。
@Configuration public class RestClientConfig { @Bean("A_site_API") public RestClient A_site_API() { return RestClient.builder() .baseUrl("https://a.com/api") .defaultHeaders(e -> e.addAll(CollectionUtils.toMultiValueMap(Map.of( HttpHeaders.AUTHORIZATION, List.of("Bearer " + "A_Site_accessToken"), HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE))))) .build(); } @Bean("B_site_API") public RestClient B_site_API() { return RestClient.builder() .baseUrl("https://b.com/api") .defaultHeaders(e -> e.addAll(CollectionUtils.toMultiValueMap(Map.of( HttpHeaders.AUTHORIZATION, List.of("Bearer " + "B_Site_accessToken"), HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE))))) .build(); } }
設定はいいのですが、呼び出しを行うときに、同じ型なので@Qualifier
で解決する必要があります。
DIの呼び出しコード
通常下記のような呼び出しを書きますが、下記だとSpringBoot起動時にエラーになってしまいます。
@Repository @RequiredArgsConstructor public class A_SiteRepositoryImpl implements A_SiteRepository { private final RestClient restClient; @Override public ResponseEntity<String> createMeeting(CreateRoomModel form) { return restClient.get().uri("/xxlist").retrieve().toEntity(String.class); } } ===== 下記のようなエラーログがでます Parameter 0 of constructor in jp.co.excite.x_dental.api.repository.webmeeting.MeetingRepositoryImpl required a single bean, but 3 were found: - A_site_API: defined by method 'A_site_API' in class path resource [jp/co/excite/x_dental/api/config/RestClientConfig.class] - B_site_API: defined by method 'B_site_API' in class path resource [jp/co/excite/x_dental/api/config/RestClientConfig.class] - whereByRestClient: defined by method 'whereByRestClient' in class path resource [jp/co/excite/x_dental/api/config/RestClientSetting.class]
では、フィールドに@Qualifier
のアノテーションをつけて起動しても、やはりSpringBoot起動時にエラーになってしまいます。
@Repository @RequiredArgsConstructor public class A_SiteRepositoryImpl implements A_SiteRepository { @Qualifier("A_site_API") private final RestClient restClient; @Override public ResponseEntity<String> createMeeting(CreateRoomModel form) { return restClient.get().uri("/xxlist").retrieve().toEntity(String.class); } } ===== 下記のようなエラーログがでます Parameter 0 of constructor in jp.co.excite.x_dental.api.repository.webmeeting.MeetingRepositoryImpl required a single bean, but 3 were found: - A_site_API: defined by method 'A_site_API' in class path resource [jp/co/excite/x_dental/api/config/RestClientConfig.class] - B_site_API: defined by method 'B_site_API' in class path resource [jp/co/excite/x_dental/api/config/RestClientConfig.class] - whereByRestClient: defined by method 'whereByRestClient' in class path resource [jp/co/excite/x_dental/api/config/RestClientSetting.class]
このエラーはlombok.configの設定で回避できます。
lombok.configでの設定
lombok.configで下記の設定を行うと、上記のエラーがなくなり起動ができます。
lombok.copyableAnnotations+=org.springframework.beans.factory.annotation.Qualifier
DIだけのためにコンストラクタを書かなくてもいいので、お手軽です。
まとめ
Lombokを使っていますけど、ドキュメントの読み込みは大事だなと思いました。とても便利なのでぜひお試しください。
最後に
エキサイトではフロントエンジニア、バックエンドエンジニア、アプリエンジニアを随時募集しております。長期インターンも歓迎していますので、興味があれば連絡いただければと思います。
募集職種一覧はこちらになります!(カジュアルからもOK) www.wantedly.com