可能我的问题是错误的,我不能这样做,但我找不到一个好的解释。
这是我的类(class)和 Spring 的注入(inject):
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 中的私有(private)字段,并且在两次执行之一中这些值可能不会正确?我错了吗?
如果有人调用 a.doSomething() 并终止,然后在另一个类中(通过注入(inject))使用 B,该怎么办?最后一个类可以有一个预先初始化的 B 实例吗?
如果我的问题不清楚,请告诉我,我的 Java 和英语也不太好:D
最佳答案
What if I'll have two concurrent calls to a.doSomething(..)? The second call will overwrite the private fields in B and probably the values will not be corret in one of the two executions? Am I wrong?
list
属性将被分配两次。如果 B#doOtherStuff
所做的不仅仅是分配 list
的值,那么您很可能会得到 ConcurrentModificationException
或者可能是意外的结果。
当您遇到这种情况时,bean 需要维护依赖于执行的可变状态,那么您的 bean 不应该处于 Singleton 范围内。最好的选择是将 bean 声明为 prototype ,每次由 Spring IoC 容器创建。
重要的是要知道,如果将原型(prototype) bean 注入(inject)到单例 bean 中,那么 IoC 容器将仅创建原型(prototype) bean 的单个实例,从而使其实际上是单例。为了避免这种行为,您可以要求 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);
}
}
更多信息:
关于java - Spring注入(inject)、全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48550067/