@Value字段,Lombok和构造函数注入的最佳实践?

56

我正在开发一个Java Spring应用程序。 我的应用程序中有一些字段是使用.yml配置文件进行配置的。 我想使用@Value注释在相关字段上导入这些值。 我还想使用构造函数注入而不是字段注入的最佳实践,但我想使用Lombok编写我的构造函数,而不是手动编写。 有没有办法同时完成所有这些事情? 例如,以下代码类似于我想做的事情,但无法正常工作:

@AllArgsConstructor
public class my service {
    @Value("${my.config.value}")
    private String myField;

    private Object myDependency;

    ...
}
在这种情况下,我想要的是Lombok生成一个只设置myDependency的构造函数,并从我的配置文件中读取myField。
谢谢!

2
构造函数注入是首选,但我不认为它与@ConfigurationProperties兼容,而这是特定的最佳实践。 - chrylis -cautiouslyoptimistic-
2个回答

57
您需要使用@RequiredArgsConstructor注解,并将myDependency标记为final。在这种情况下,Lombok将基于'required' final字段生成一个构造函数作为参数,例如:
@RequiredArgsConstructor
@Service
public class MyService {

    @Value("${my.config.value}")
    private String myField;

    private final MyComponent myComponent;

    //...
}

这等同于以下内容:

@Service
public class MyService {

    @Value("${my.config.value}")
    private String myField;

    private final MyComponent myComponent;

    public MyService(MyComponent myComponent) { // <= implicit injection
        this.myComponent = myComponent;
    } 

    //...
}

由于只有一个构造函数,Spring会在没有显式使用@Autowired注解的情况下注入MyComponent更多信息请参考Spring Boot文档中关于Bean和依赖注入的章节。


Spring如何知道要将哪个Bean注入到myComponent字段中?通常情况下,您需要使用类似@Autowired的注释来实现,是吗? - Gustavo Passini
4
如果一个bean只有一个构造函数,你可以省略 @Autowired。 - Cepr0
5
对于那些不想被最终关键字限制的人,他们可以使用@NonNull(lombok)注释。 - Mr.Q
3
myField 上有 @Value 注解怎么办? - manikanta
3
你如何使用myField测试这个类? - Andrii Bobrov
显示剩余3条评论

49

请确保您至少使用 Lombok 1.18.4 版本,并将所需的注释添加到 lombok.config 文件中。

lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Value

这是你的类:

@AllArgsConstructor(onConstructor = @__(@Autowired))
public class MyService{

    @Value("${my.config.value}")
    private String myField;

    private Object myDependency;
}

这里是 Lombok 生成的类:

public class MyService {

@Value("${my.config.value}")
private String myField;

private Object myDependency;

@Autowired
@Generated
public MyService(@Value("${my.config.value}") final String myField, final Object myDependency) {
    this.myField = myField;
    this.myDependency = myDependency;
}

提示:请确保您的lombok.config文件位于/src/main/java文件夹下。我试过将其添加到/src/main/resources,但没有成功。

来自Lombok - 在构造函数的输入参数中保留字段注释的回复。


在构造函数上不需要使用@Autowired - Saljack
这就是 Lombok 生成类的方式。我无法控制生成的代码。 - octavian
7
我认为@Saljack所指出的是,@AllArgsConstructor(onConstructor = @__(@Autowired))@Autowired 添加到构造函数中,这是不必要的。 - Kricket
对我来说,在Gradle/Maven项目的根目录中放置lombok.config文件是有效的。 - Harold L. Brown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接