[英]Spring injection, global variables
我的问题可能是错误的,我不能这样做,但是找不到很好的解释。
这是我的课程和对Spring的投入:
public class A
{
@Autowired
protected B b;
public void doSomething(Integer i)
{
b.doOtherStuff(i);
}
}
这是我的B课:
public class B
{
private Integer field;
private List<SomeOtherClass> list = new ArrayList<>();
@Autowired
protected C c;
public void doOtherStuff(Integer in)
{
field = in;
list = c.getMyList(i);
}
}
如果我要同时对a.doSomething(..)进行两次调用怎么办? 第二次调用将覆盖B中的私有字段,并且可能不会在两个执行之一中将值正确化? 我错了吗?
如果有人调用a.doSomething()并终止,后来在另一个类中使用B(通过注入)怎么办? 最后一个类是否可以预先初始化B的实例?
如果我的问题不清楚,请告诉我,我的Java和英语也不太好:D
如果我要同时对a.doSomething(..)进行两次调用怎么办? 第二次调用将覆盖B中的私有字段,并且可能不会在两个执行之一中将值正确化? 我错了吗?
list
属性将被分配两次。 如果B#doOtherStuff
不仅仅是分配list
的值,那么您很可能会收到ConcurrentModificationException
或意外的结果。
在这种情况下,当Bean需要维护依赖于执行的可变状态时,则Bean不应处于Singleton范围内。 最好的选择是将bean声明为prototype ,它由Spring IoC容器每次创建。
重要的是要知道,如果将原型Bean注入到一个Singleton Bean中,那么IoC容器将仅创建该原型Bean的单个实例,从而使其实际上成为Singleton。 为了避免这种行为,您可以要求ApplicationContext在每次方法执行时检索一个新实例:
@Component
public class A {
@Autowired
private ApplicationContext ctx;
public void doSomething(Integer i) {
//ApplicationContext will create the bean using the IoC container
B b = ctx.getBean(B.class);
b.doOtherStuff(i);
}
}
更多信息:
您认为私有变量是bean中的问题是正确的。 您可能需要阅读有关bean作用域的内容 。 缺省的bean作用域是singleton,这意味着对于所有调用而言,只有一个实例可以使用。
这也意味着您的私有变量将通过对Bean的所有调用来共享。 因此,在类B中,每次调用方法doOtherStuff
都会覆盖变量field
。
通常,除非更改范围,否则在Spring bean中拥有私有变量是很糟糕的。 对此有一些例外,例如某些缓存或任何其他共享的和线程安全的逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.