【问题标题】:Spring @Autowired and @Value on property not working属性上的 Spring @Autowired 和 @Value 不起作用
【发布时间】:2018-02-12 15:04:20
【问题描述】:

我想在属性上使用@Value,但我总是得到0(on 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???
    }
}

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

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

【问题讨论】:

  • 构造函数和类名不匹配,我猜是错字
  • Spring如何在一个甚至不存在的对象上设置一个值...一个对象在构造函数执行后存在。

标签: java spring spring-boot dependency-injection property-injection


【解决方案1】:

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

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

@Component
public class FtpServer {

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

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

}

【讨论】:

  • 我不知道@PostConstruct 注释...+1 我学到了一些新东西!
【解决方案2】:

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

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

    FtpServer ftpServer=new FtpServer(<value>);

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

    code equivalent to ftpServer.setPort(<value>)

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

【讨论】:

    【解决方案3】:

    这是成员注入:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-10
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2011-08-06
      • 2012-03-31
      • 1970-01-01
      相关资源
      最近更新 更多