Spring 5 如何处理 null Beans 的变化?

IT小君   2023-09-16T19:40:04
所以,我有以下的应用程序:
@SpringBootApplication
public class AutonullApplication {

  public static void main(String[] args) {
    SpringApplication.run(AutonullApplication.class, args);
  }

  @Bean
  First first() {
    return null;
  }

  public class First {
  }

  @Service
  public class Second {

    private final First first;

    public Second(First first) {
      this.first = first;
    }

    @PostConstruct
    public void print() {
      System.out.println("First = " + first);
    }
  }

}
尝试将一个类型为First的bean注入到一个类型为Second的服务中。但是该bean的值是null。这段代码在Spring Boot 1.5.10(以及Spring 4)中运行正常,但在Spring Boot 2.0(以及Spring 5)中失败:

描述:

eu.plumbr.autonull.AutonullApplication$Second的构造函数的第一个参数需要一个类型为'eu.plumbr.autonull.AutonullApplication$First'的bean,但找不到。

有没有人知道官方文档中有关此更改的任何提及?
评论(2)
IT小君

是的,这是Spring Framework 5中的一个重大变化。可以说,这样的设置很奇怪,我们想要稍微加强这些规则。

如果你请求注入First,并且提供了null,那么更一致的做法是认为没有提供该bean。然后你可以查询上下文是否存在First。@spencergibb已经解释了你可以如何使用Optional,或者你可以使用ObjectProvider<First>作为注入点:

@Service
public class Second {

    private final First first;

    public Second(ObjectProvider<First> first) {
        this.first = first.getIfAvailable(); // 返回null
    }

}
2023-09-16T19:40:18   回复
IT小君

使用Java 8的空安全方式,可以使用Optional类。

@Service
public class Second {

  private final Optional<First> first;

  public Second(Optional<First> first) {
    this.first = first;
  }

  @PostConstruct
  public void print() {
    System.out.println("First = " + first.orElse(null));
  }
}
2023-09-16T19:40:32   回复