10

我想@Value在一个属性上使用,但我总是得到0(在 int 上)。
但是在构造函数参数上它可以工作。

例子:

@Component
public class FtpServer {

    @Value("${ftp.port}")
    private int port;

    public FtpServer(@Value("${ftp.port}") int port) {
        System.out.println(port); // 21, loaded from the application.properties.
        System.out.println(this.port); // 0???
    }
}

该对象是弹簧管理的,否则构造函数参数将不起作用。

有谁知道是什么导致了这种奇怪的行为?

4

3 回答 3

22

字段注入是在构造对象之后完成的,因为显然容器不能设置不存在的东西的属性。该字段将始终在构造函数中未设置。

如果你想打印注入的值(或者做一些真正的初始化:)),你可以使用一个用 注释的方法@PostConstruct,它会在注入过程之后执行。

@Component
public class FtpServer {

    @Value("${ftp.port}")
    private int port;

    @PostConstruct
    public void init() {
        System.out.println(this.port);
    }

}
于 2017-09-04T11:29:56.940 回答
7

我认为问题是由于Spring的执行顺序引起的:

  • 首先,Spring 调用构造函数来创建一个实例,类似于:

    FtpServer ftpServer=new FtpServer(<value>);

  • 之后,通过反射,属性被填充:

    code equivalent to ftpServer.setPort(<value>)

因此,在构造函数执行期间,该属性仍为 0,因为这是 a 的默认值int

于 2017-09-04T11:29:45.357 回答
1

这是一个成员注入:

@Value("${ftp.port}")
private int port;

在从其构造函数实例化 bean 之后,哪个 spring 会执行此操作。所以在 spring 从类中实例化 bean 的时候,spring 没有注入这个值,这就是为什么你得到默认的 int 值 0。

确保在 spring 调用构造函数之后调用变量,以防你想坚持成员注入。

于 2017-09-04T18:19:06.260 回答