簡體   English   中英

Spring @Autowired 字段 - 哪個訪問修飾符是私有的還是包私有的?

[英]Spring @Autowired fields - which access modifier, private or package-private?

假設我們在類中的各個字段上使用@Autowired注釋,並且我們沒有編寫也可以設置字段的 setter 或構造函數。

問題 - 訪問修飾符應該是什么, privatepackage-private (即無)?

例如:

public class MyClass {
    @Autowired
    private MyService myService;
}

對比

public class MyClass {
    @Autowired
    MyService myService;
}

在第一種情況下( private字段)Spring 使用反射來連接字段,即使它沒有設置器。

第二種情況( package-private字段)允許我們在需要擴展類以進行測試時訪問這些字段(例如,設置模擬)。

所以這兩種情況都可以正常工作,但更推薦哪種情況,特別是在測試方面?

所以這兩種情況都可以正常工作,但更推薦哪種情況,特別是在測試方面?

我認為這些屬性應該是private

@Autowired
private MyService myService;

因為使用 getter 方法來提供對屬性的訪問而不是允許其他類直接訪問它們總是好的。

而對於測試的目的,注射mocksprivate properties的工作方式為相同的package-private性質。

例如,使用Mockito ,您可以將private MyService的模擬注入MyClass如下所示:

public class MyClassTest {

    @Mock
    MyService service;

    @InjectMocks
    MyClass serv = new MyClass();

    @Before
    public void init() {
    MockitoAnnotations.initMocks(this);
    }
}

我通常更喜歡將字段設為私有並使用 setter 注入:

public class MyClass {

    private MyService myService;

    @Autowired
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
}   

允許服務@Autowired,但設置為單元測試的模擬實例。

第一種情況還允許您根據框架注入模擬。 例如使用@InjectMocks注釋。 您在 Spring 測試中也有ReflectionTestUtils.setField ,...

我個人不太喜歡為了測試目的而過多地修改類,所以我會選擇第一種情況。 但歸根結底,這主要取決於您首選的測試框架。

我通常不會將 @Autowired 用於私有字段或方法。 @Autowired 的意思是,外面的人會設置這個字段。 另一方面,“私有”意味着除了這個類之外沒有人被允許使用它。

如果 JIT 編譯器以某種方式優化此代碼,理論上混合 @Autowired 和私有會導致問題。 它可能是與 Java 內存模型並發相關的問題,這將是僅限生產且無法重現的。

我會讓 Autowired 字段至少包可見。 作為免費獎勵,它將允許在沒有技巧和變通方法的情況下編寫單元測試。

更新:此外,我會將此類字段聲明為volatile以避免與 Java 內存模型相關的可見性沖突。 Spring 開發人員做了一些技巧來使自動裝配的字段在不顯式同步訪問的情況下工作,但我不確定這些技巧在任何硬件上的任何 JVM 中都能順利運行。


我寧願在 @Autowired 字段上使用 private ,原因如下:

  • 我將這些字段用於依賴注入,通常在服務類中,以使用其他服務類。 在這種情況下,我想將這些字段保留在當前類中。
  • 此外,擴展這個類會導致不同的邏輯,所以可能需要@Autowired 字段的另一個實現,因此私有而不是包私有。
  • 此外,在重構時,有助於查看何時不再使用此類字段,因為包私有字段在未使用時不會顯示警告(假設您的 IDE 是 Eclipse - 我實際上不知道其他 IDE)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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