知識庫 / Spring RSS 訂閱

Spring 核心註解

Spring
HongKong
5
01:46 PM · Dec 06 ,2025
<div>
 <a class="article-series-header" href="javascript:void(0);">該文章是系列中的一部分</a>
 <div>
  <div>
   <div>
    • Spring Core 註解 <span>(當前文章)</span>
   </div>
   • Spring Web 註解
   <br>
   • Spring Boot 註解
   <br>
   • Spring Scheduling 註解
   <br>
   • Spring Data 註解
   <br>
   • Spring Bean 註解
   <br>
  </div>
  <!-- end of article series inner -->
 </div>
 <!-- .article-series-links -->
</div>
<!-- end of article series section -->

1. 概述

我們可以利用 Spring DI 引擎中的註解,通過 org.springframework.beans.factory.annotationorg.springframework.context.annotation 包來實現。

我們通常將這些註解稱為“Spring 核心註解”,並在本教程中進行回顧。

2. DI 相關注釋

2.1. <em @Autowired

我們可以使用 <em @Autowired> 來標記一個 Spring 將要解析並注入的依賴項。 我們可以使用此註解與構造函數、設置方法或字段注入一起使用。

構造函數注入:

class Car {
    Engine engine;

    @Autowired
    Car(Engine engine) {
        this.engine = engine;
    }
}

Setter 注入:

class Car {
    Engine engine;

    @Autowired
    void setEngine(Engine engine) {
        this.engine = engine;
    }
}

字段注入:

class Car {
    @Autowired
    Engine engine;
}

@Autowired 具有一個 boolean 類型的參數 required,默認值為 true。它調整 Spring 的行為,當找不到合適的 Bean 進行注入時。當 true 時,會拋出異常,否則什麼也不進行注入。

注意,如果使用構造函數注入,所有構造函數參數都必須是必需的。

從 4.3 版本開始,除非我們聲明至少有兩個構造函數,否則我們無需顯式地使用 @Autowired 註解來標註構造函數。

有關更多詳細信息,請參閲我們關於 @Autowired 和構造函數注入的文章。

2.2. <em @Bean@

@Bean 標記了一個工廠方法,用於實例化一個 Spring Bean。

@Bean
Engine engine() {
    return new Engine();
}

Spring 在需要創建返回類型的新的實例時,會調用這些方法。

生成的 Bean 的名稱與工廠方法相同。如果希望將其命名為不同,可以使用 namevalue 屬性(value 屬性是 name 屬性的別名)進行指定:

@Bean("engine")
Engine getEngine() {
    return new Engine();
}

請注意,所有帶有 @Bean 註解的方法必須位於 @Configuration 類中。

2.3. <em @Qualifier</em>

我們使用 <em @Qualifier</em><em @Autowired</em> 共同提供在歧義情況下我們想要使用的 Bean ID 或 Bean 名稱。

例如,以下兩個 Bean 實現相同的接口:

class Bike implements Vehicle {}

class Car implements Vehicle {}

如果 Spring 需要注入一個 Vehicle Bean,它可能會遇到多個匹配的定義。 在這種情況下,我們可以使用 @Qualifier 註解顯式指定 Bean 的名稱。

使用構造注入:

@Autowired
Biker(@Qualifier("bike") Vehicle vehicle) {
    this.vehicle = vehicle;
}

使用 setter 注入:

@Autowired
void setVehicle(@Qualifier("bike") Vehicle vehicle) {
    this.vehicle = vehicle;
}

或者:

@Autowired
@Qualifier("bike")
void setVehicle(Vehicle vehicle) {
    this.vehicle = vehicle;
}

使用字段注入:

@Autowired
@Qualifier("bike")
Vehicle vehicle;

欲瞭解更詳細的描述,請閲讀本文。

2.4. @Value

我們可以使用 @Value 將屬性值注入到 Bean 中。它與構造函數注入、setter 注入和字段注入兼容。

構造函數注入:

Engine(@Value("8") int cylinderCount) {
    this.cylinderCount = cylinderCount;
}
<p>Setter injection:</p>
@Autowired
void setCylinderCount(@Value("8") int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

或者:

@Value("8")
void setCylinderCount(int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

字段注入:

@Value("8")
int cylinderCount;

當然,注入靜態值並非有效。因此,我們可以使用 佔位符字符串@Value 中來連接來自 外部來源 的值,例如在 .properties.yaml 文件中。

讓我們假設以下 .properties 文件:

engine.fuelType=petrol

我們可以通過以下方式注入 engine.fuelType 的值:

@Value("${engine.fuelType}")
String fuelType;

我們可以使用 @Value 甚至與 SpEL 結合使用。 更多高級示例請參考我們關於 @Value 的文章。

2.5. <em @DependsOn</em>>

我們可以使用此註解來使 Spring 在註解類執行之前初始化其他 Bean。通常,這種行為是自動的,基於 Bean 之間的顯式依賴關係。

我們只需要此註解,當依賴關係是隱式的,例如 JDBC 驅動程序加載或靜態變量初始化。

我們可以使用 <em @DependsOn</em>> 在依賴類上指定依賴 Bean 的名稱。該註解的 <em value</em> 參數需要一個包含依賴 Bean 名稱的數組:

@DependsOn("engine")
class Car implements Vehicle {}

如果定義了一個帶有 @Bean 標註的 Bean,則工廠方法應使用 @DependsOn 標註:

@Bean
@DependsOn("fuel")
Engine engine() {
    return new Engine();
}

2.6. <em @Lazy</em>>

我們使用 <em @Lazy</em>> 當我們希望延遲初始化我們的 Bean 時。默認情況下,Spring 在應用程序上下文的啓動/構建過程中會立即創建所有單例 Bean。

然而,在某些情況下,我們需要在請求 Bean 時創建它,而不是在應用程序啓動時創建。

此註解的行為取決於我們將其放置的確切位置。我們可以將其放置在:

  • 一個帶有 `>` 註解的 Bean 工廠方法上,以延遲方法調用(從而延遲 Bean 的創建)
  • 一個 `` 類及其包含的所有 `>` 方法將會受到影響
  • 一個不 являться `` 類的 `` 類,此 Bean 將會延遲初始化
  • 一個 `` 構造函數、設置方法或字段,以延遲加載依賴項本身(通過代理)

此註解有一個名為 <em value</em> 的參數,默認值為 `<em true>。它對於覆蓋默認行為很有用。

例如,當全局設置設置為延遲時,標記 Bean 以立即加載,或者在帶有 <em @Lazy</em>> 註解的 <em @Configuration</em> 類中配置特定 <em @Bean</em>> 方法以進行立即加載:

@Configuration
@Lazy
class VehicleFactoryConfig {

    @Bean
    @Lazy(false)
    Engine engine() {
        return new Engine();
    }
}

欲瞭解更多信息,請訪問本文。

2.7. <em @Lookup</em>

一個帶有 `` 註解的方法,會告訴 Spring 在調用該方法時,返回該方法返回類型的實例。

關於該註解的詳細信息,請參考本文。

2.8. <em @Primary</em>>

有時我們需要定義同類型的多個Bean。在這種情況下,注入將失敗,因為Spring無法確定需要哪個Bean。

我們之前已經看到了一種處理這種情況的方法:使用<em @Qualifier</em>>標記所有注入點,並指定所需Bean的名稱。

然而,大多數情況下,我們只需要特定的Bean,而很少需要其他的。我們可以使用<em @Primary</em>>來簡化這種情況:如果我們用<em @Primary>標記最常用的Bean,它將在未限定注入點上被選中:

@Component
@Primary
class Car implements Vehicle {}

@Component
class Bike implements Vehicle {}

@Component
class Driver {
    @Autowired
    Vehicle vehicle;
}

@Component
class Biker {
    @Autowired
    @Qualifier("bike")
    Vehicle vehicle;
}

在之前的示例中,Car 是主要的車輛。因此,在 Driver 類中,Spring 注入了一個 Car Bean。當然,在 Biker Bean 中,字段 vehicle 的值將是一個 Bike 對象,因為它是明確指定的。

2.9. @Scope

我們使用 @Scope 來定義 @Component 類或 @Bean 聲明的範圍。它可以是 singleton, prototype, request, session, globalSession 或自定義範圍。

例如:

@Component
@Scope("prototype")
class Engine {}

3. 上下文配置註釋

我們可以使用本節中描述的註釋來配置應用程序上下文。

3.1. <em @Profile@

如果希望 Spring 只在特定 profile 激活時使用 @Component 類或 @Bean 方法,我們可以使用 註解標記它們。可以使用註解的 參數配置 profile 的名稱。

@Component
@Profile("sportDay")
class Bike implements Vehicle {}

您可以在這篇文章中瞭解更多關於“配置文件”的信息。

3.2. <em @Import</em>>

我們可以使用此註解,在不進行組件掃描的情況下,使用特定的 <em @Configuration</em>> 類。 通過將 <em @Import</em>><em value</em> 參數提供給這些類來實現:

@Import(VehiclePartSupplier.class)
class VehicleFactoryConfig {}

3.3. <em @ImportResource</em>>

我們可以使用此註解導入 XML 配置。可以使用 <em location</em>> 參數或其別名 <em value</em>> 參數指定 XML 文件位置:

@Configuration
@ImportResource("classpath:/annotations.xml")
class VehicleFactoryConfig {}

3.4. <em @PropertySource

使用此註解,我們可以定義應用程序設置的屬性文件

@Configuration
@PropertySource("classpath:/annotations.properties")
class VehicleFactoryConfig {}

@PropertySource 利用了 Java 8 的重複註解特性,這意味着我們可以用它標記一個類多次:

@Configuration
@PropertySource("classpath:/annotations.properties")
@PropertySource("classpath:/vehicle-factory.properties")
class VehicleFactoryConfig {}

3.5. <em @PropertySources@

我們可以使用此註解來指定多個 <em @PropertySource@> 配置:

@Configuration
@PropertySources({ 
    @PropertySource("classpath:/annotations.properties"),
    @PropertySource("classpath:/vehicle-factory.properties")
})
class VehicleFactoryConfig {}

請注意,自 Java 8 以來,我們就可以通過重複註解功能(如上文所述)來實現相同的結果。

4. 結論

在本文中,我們對 Spring 核心註解進行了概述。我們瞭解瞭如何配置 Bean 注入和應用上下文,以及如何標記類以供組件掃描。

下一部分 »
Spring Web 註解
user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.