簡體   English   中英

彈簧注入,全局變量

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM