環境
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
ソースコードなど
コンストラクタ引数にValueを付与
あるプロパティを初期化時にのみ使用する、などの場合は以下のように自前のコンストラクタで十分と思われる。
@Component
public class Valueconstrucor {
public Valueconstrucor(@Value("${prop.sample}") String value) {
System.out.println(value);
}
}
lombokのRequiredArgsConstructorと併用
lombokでコンストラクタを自動生成しつつプロパティも必要な場合は以下にならざるを得ない。constructor-injectionとfield-injectionをするのは不格好というか、出来れば前者にまとめたい。以降でこれの解決方法について述べる。
@Component
@RequiredArgsConstructor
public class Valueconstrucor2 {
final SampleService1 service1;
@Value("${prop.sample}")
String value;
// 以下省略
これの解決には、lombok設定でフィールドのアノテーションをコンストラクタ引数にコピーする機能があるのでこれを使用する。詳細は https://projectlombok.org/features/constructor のlombok.copyableAnnotations
を参照。
src\main\java\lombok.config
を作成して以下のようにする。これで@Value
がコピーされるようになる。
lombok.config
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Value
上記設定により、以下は意図通りのコンストラクタが生成される。
@Component
@RequiredArgsConstructor
public class Valueconstrucor3 {
final SampleService1 service1;
@Value("${prop.sample}")
final String value;
// 以下省略
自動生成されるコードは以下の通り。
@Component
public class Valueconstrucor3 {
final SampleService1 service1;
@Value("${prop.sample}")
final String value;
public void execute() {
System.out.println(this.value);
}
@Generated
public Valueconstrucor3(final SampleService1 service1, @Value("${prop.sample}") final String value) {
this.service1 = service1;
this.value = value;
}
}
感想
個人的には、あまりlombokに頼りすぎず手動でコンストラクタを書いちゃっても良いかな……と思わないでもない。依存先が2,3つなら大してソースコードも膨らまないし。もしそれ以上になって自動生成に頼りたくなるのならクラス間の依存関係に別の問題があるんじゃなかろうか。