简述
ObjectProvider是spring 4.3版本才有的新东西,专为注入时使用,允许编程可选性和宽松的非唯一处理。
构造函数隐式注入
4.3系列之前版本,如果你构造函数中要依赖另外一个bean,你必须显示依赖@Autowired ,像这样子:
@Service
public class FooService {
private final FooRepository repository;
@Autowired
public FooService(FooRepository repository) {
this.repository = repository
}
}
相当常见的用例,但是如果你忘记构造函数上的@Autowired注解,容器将抛出一个寻找默认构造函数的异常,除非你在该bean的BeanDefinition中设置中明确指出autowire模式'constructor'。
因此,从4.3开始,已经不再需要在这样的单构造函数场景中指定显式注入注解。对于那些根本不带任何容器注解的类来说,这是特别优雅的,FooService会从beanFactory中查找FooRepository。
同样,@Configuration类历史上不支持构造函数注入。从4.3开始,它们也允许在单构造函数场景中省略@Autowired
@Service
public class FooService {
private final FooRepository repository;
public FooService(FooRepository repository) {
this.repository = repository
}
}
@Configuration
public class FooConfiguration {
private final FooRepository repository;
public FooConfiguration(FooRepository repository) {
this.repository = repository
}
@Bean
public FooService fooService() {
return new FooService(this.repository);
}
}
但是隐式注入也不是完美的,个人理解不完美是它是强依赖,如果这个依赖不存在,就会发生这样的悲剧:
*Parameter 0 of constructor in com.example.demo.FooRepository required a bean of type 'com.example.demo.OrderServiceV2' that could not be found.
ObjectProvider就可以解决这个问题
依赖关系的改进版编程
Spring Framework 4.3引入了ObjectProvider,它是现有ObjectFactory接口的扩展,具有方便的签名,例如getIfAvailable和getIfUnique,只有在它实际存在时才检索bean(可选支持)或者如果可以确定单个候选者(特别是:主要候选者)在多个匹配的bean的情况下)
@Service
public class FooService {
private final FooRepository repository;
public FooService(ObjectProvider<FooRepository> repositoryProvider) {
this.repository = repositoryProvider.getIfUnique();
}
}