[英]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.