Using java javax.inject.Provider with Spring @Scope(BeanDefi



有人可以解释一下,将提供者与SCOPE_PROTOTYPE结合起来有意义吗?因为,每次注入 SocketSender 时,我都会因为SCOPE_PROTOTYPE而得到一个新的 SocketSender 对象?将这两者结合起来似乎毫无意义。请参阅下面的代码。 这两种实现之间有什么区别吗?提前谢谢。

@Configuration
public class SpringConfiguration {
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public SocketSender getSender() {
return new SocketSender();
}
}

//First implementation
class MyServiceImpl{
private Provider<SocketSender> socketSender;
@Inject
public MyServiceImpl(Provider<SocketSender> socketSender){
this.socketSender=socketSender;
}
public void doSomething(){
socketSender.get().doAnotherThing();
}  
}

//Second implementation
class MyServiceImpl{
private SocketSender socketSender;
@Inject 
public MyServiceImpl(SocketSender socketSender){
this.socketSender=socketSender;
}
public void doSomething(){
socketSender.doAnotherThing();
}  
}

基本上这取决于你做什么,有时使用Provider是一个不错的选择,有时它不是。

例如,如果你有一些类MyService需要调用一个 bean,MyBuilder应该为该方法的每次调用创建foo因为它在内部保存状态(,那么对MyBuilder使用原型作用域和对MyService使用单例作用域是有意义的。

如果我们使用简单的实现:

// singleton bean
class MyService  {
// defined as a prototype in spring, but what about injection?
@Autowired
private MyBuilder myBuilder;
public void foo(int param) {
Product p = myBuilder.withParam(param).build();
... 
}
}

如果无法按预期工作:myBuilder对象将被重用,它将始终是同一个对象...... 发生这种情况是因为 Spring 仅在初始化单例时将原型注入单例一次,并且因为它总是相同的引用。

为了解决这个问题,您可以使用Provider

class MyService {
private Provider<MyBuilder> myBuilder;
public void foo(int param) {
Product p = myBuilder.get().withParam(param).build();
...
}
}

现在,foo方法的不同调用将适用于不同的myBuilder实例。

最新更新