自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

請(qǐng)不要再使用@Autowired/@Resource注解進(jìn)行字段注入

開發(fā) 前端
我們需要在聲明或通過構(gòu)造函數(shù)實(shí)例化最終字段。此外,一旦構(gòu)造函數(shù)被調(diào)用,Spring 就會(huì)執(zhí)行自動(dòng)裝配。因此,不可能使用字段注入方式來裝配最終字段。

1. 簡(jiǎn)介

對(duì)象在無需定義或創(chuàng)建其依賴對(duì)象的情況下使用這些依賴對(duì)象的過程被稱為依賴注入。這是Spring框架的核心功能之一。

我們可以通過三種方式注入依賴對(duì)象:

  • 構(gòu)造函數(shù)注入
  • Setter注入
  • 字段注入

而這里的字段注入是使用 @Autowired 注解將依賴關(guān)系直接注入類中。雖然這可能是最簡(jiǎn)單的方法,但我們必須明白它可能會(huì)導(dǎo)致一些潛在的問題。而且,甚至Spring的官方文檔也不再將字段注入列為依賴注入的選項(xiàng)之一。如下官方文檔:

圖片圖片

2. 引發(fā)的問題

2.1 空安全(Null-Safety)

如果未正確初始化依賴關(guān)系,字段注入會(huì)產(chǎn)生 NullPointerException 風(fēng)險(xiǎn)。如下示例:

@Repository
public class PersonDAO {
}
@Service
public class PersonService {
  // @Autowired
  @Resource
  private PersonDAO dao ;
  public String toString() {
    return "PersonService [dao=" + dao + "]";
  }
}

在上面的示例中,只有容器中存在 PersonDAO 依賴項(xiàng),PersonService才能正常工作。然而,在使用字段注入時(shí),我們沒有提供直接實(shí)例化 PersonService 所需的依賴關(guān)系的方法。

使用@Autowired時(shí),啟動(dòng)容器會(huì)報(bào)錯(cuò),這也還算好,如果我們?nèi)缦率褂茫?/p>

@Autowired(required = false)

容器啟動(dòng)將正常,但是如果當(dāng)調(diào)用方法時(shí)將出現(xiàn)NPE。這里如果你使用@Resource也會(huì)出現(xiàn)NPE問題。

此外,我們還可以使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建 PersonService 實(shí)例:

PersonService ps = new PersonService() ;
ps.xxx() ;

這都將導(dǎo)致NPE問題。

對(duì)于這NPE問題,我們可以通過構(gòu)造函數(shù)注入來降低NPE問題。

private final PersonDAO dao ;
public PersonService(PersonDAO dao) {
  this.dao = dao ;
}

通過這種方法,我們公開了所需的依賴關(guān)系。此外,我們現(xiàn)在要求客戶提供必須的依賴項(xiàng)。換句話說,如果不提供 PersonDAO 實(shí)例,就無法創(chuàng)建新的 PersonService 實(shí)例。

2.2 不變性(Immutability)

使用字段注入,我們無法創(chuàng)建不可變類。

我們需要在聲明或通過構(gòu)造函數(shù)實(shí)例化最終字段。此外,一旦構(gòu)造函數(shù)被調(diào)用,Spring 就會(huì)執(zhí)行自動(dòng)裝配。因此,不可能使用字段注入方式來裝配最終字段。

由于依賴關(guān)系是可變的,我們無法確保它們?cè)诔跏蓟蟊3植蛔?。此外,重新分配非最終字段可能會(huì)在運(yùn)行應(yīng)用程序時(shí)產(chǎn)生意想不到的副作用?;蛘撸覀兛梢詫?duì)強(qiáng)制依賴關(guān)系使用構(gòu)造器注入,對(duì)可選依賴關(guān)系使用setter注入。這樣,我們就能確保所需的依賴關(guān)系保持不變。

2.3 設(shè)計(jì)問題

違反單一職責(zé)

作為SOLID原則的一部分,單一職責(zé)原則規(guī)定每個(gè)類應(yīng)該只有一項(xiàng)職責(zé)。換句話說,一個(gè)類應(yīng)該只負(fù)責(zé)一個(gè)操作,因此只有一個(gè)改變的理由。

當(dāng)我們使用字段注入時(shí),最終可能會(huì)違反單一責(zé)任原則。我們很容易添加超出必要的依賴關(guān)系,并創(chuàng)建一個(gè)身兼多職的類。

另一方面,如果我們使用構(gòu)造函數(shù)注入,我們就會(huì)發(fā)現(xiàn),如果一個(gè)構(gòu)造函數(shù)有超過幾個(gè)依賴關(guān)系,我們可能會(huì)遇到設(shè)計(jì)問題。此外,如果構(gòu)造函數(shù)中的參數(shù)超過 7 個(gè),甚至集成開發(fā)環(huán)境也會(huì)發(fā)出警告。

循環(huán)依賴問題

簡(jiǎn)單地說,當(dāng)兩個(gè)或多個(gè)類相互依賴時(shí),就會(huì)出現(xiàn)循環(huán)依賴。由于存在這些依賴關(guān)系,因此無法構(gòu)造對(duì)象,執(zhí)行過程中可能會(huì)出現(xiàn)運(yùn)行時(shí)錯(cuò)誤或無限循環(huán)。

使用字段注入可能會(huì)導(dǎo)致循環(huán)依賴被忽視,如下示例:

@Component
public class A {
  @Autowired
  private B b ;
}
@Component
public class B {
  @Autowired
  private A a ;
}

這里兩個(gè)類通過字段注入,形成循環(huán)依賴。這樣運(yùn)行不會(huì)有問題也就是并不會(huì)拋出BeanCurrentlyInCreationException 異常;簡(jiǎn)單說,對(duì)于這種循環(huán)依賴其實(shí)是一種設(shè)計(jì)的缺陷我們應(yīng)該避免,但是這里并沒有表現(xiàn)出來。

注意:在Spring環(huán)境下默認(rèn)是允許循環(huán)依賴的。 

但是在Spring Boot環(huán)境并且從2.6版本開始循環(huán)依賴默認(rèn)是不允許的,也就是上面的字段注入將拋出異常。

乘熱打鐵,接下來說說循環(huán)依賴的解決。

如果你將上面的依賴注入方式改成了構(gòu)造函數(shù),如下:

@Component
public class A {
  private B b ;
  public A(B b) {
    this.b = b ;
  }
}
@Component
public class B {
  private A a ;
  public B(A a) {
    this.a = a ;
  }
}

容器啟動(dòng)將拋出BeanCurrentlyInCreationException 異常;對(duì)于這種構(gòu)造函數(shù)的循環(huán)依賴是可以通過@Lazy解決。如下示例:

// 構(gòu)造函數(shù)上添加注解或者是在參數(shù)加都可以
// @Lazy
public A(@Lazy B b) {
  this.b = b ;
}

只要在任意一端添加了@Lazy都可解決。

最后,我們可以使用構(gòu)造器注入來代替字段注入,構(gòu)造器注入是必需的,而setter注入則是可選的。

責(zé)任編輯:武曉燕 來源: Spring全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2009-06-15 17:48:32

Spring注解注入屬性

2014-12-05 10:06:44

程序員

2025-04-08 08:25:00

前端埋點(diǎn)線程

2015-04-22 15:02:33

公共PaaSIT運(yùn)維Docker

2021-05-15 08:35:22

數(shù)據(jù)庫(kù)CAP模式

2023-09-07 17:06:21

@Autowired報(bào)錯(cuò)原因分析

2009-09-12 10:59:37

2023-03-27 21:54:48

方式OptionalAutowird

2022-09-26 10:26:27

FieldIDEASpring

2020-10-12 10:45:44

nullava程序員

2023-10-23 07:36:25

@ResourceAutowiredjavax

2023-02-17 08:02:45

@Autowired@Resource

2023-10-22 14:18:20

瀏覽器前端技術(shù)

2015-08-25 09:00:48

創(chuàng)業(yè)失敗者創(chuàng)業(yè)活動(dòng)

2011-04-15 09:44:45

Spring

2015-08-26 11:12:11

數(shù)據(jù)溢出SQL注入SQL報(bào)錯(cuò)注入

2024-03-06 08:15:03

@Autowired注入方式Spring

2022-09-27 07:31:57

Property模式數(shù)據(jù)

2013-01-10 10:16:12

2024-12-30 08:22:35

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)