最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

揭秘Spring核心注解@Configuration與@Component的本質(zhì)區(qū)別

 更新時間:2025年07月10日 08:48:08   作者:一勺菠蘿丶  
在Spring框架中,@Configuration和@Component都是常用的注解,但它們有著本質(zhì)的區(qū)別,本文將深入剖析這兩者的核心區(qū)別,并通過代碼示例展示它們的實際行為差異

引言:Spring中的兩個關(guān)鍵角色

在Spring框架中,@Configuration@Component都是常用的注解,但它們有著本質(zhì)的區(qū)別。許多開發(fā)者在使用時容易混淆它們的行為,特別是當(dāng)涉及@Bean方法時。本文將深入剖析這兩者的核心區(qū)別,并通過代碼示例展示它們的實際行為差異。

核心區(qū)別一覽表

場景被標(biāo)記的類本身類內(nèi)部調(diào)用 @Bean 方法
@Component/@Service 類默認單例每次調(diào)用都創(chuàng)建新對象
@Configuration 類默認單例調(diào)用其他 @Bean 方法返回單例

這個表格揭示了Spring中一個關(guān)鍵但常被誤解的區(qū)別:類本身的單例行為與類內(nèi)部方法調(diào)用的單例行為是不同的概念。

場景一:業(yè)務(wù)組件(@Component/@Service)

類本身的單例行為

@Service // 等同于 @Component
public class UserService {
    // 業(yè)務(wù)邏輯...
}

類本身是單例

Spring容器只會創(chuàng)建一個UserService實例

通過@Autowired注入時

注入的是同一個實例

@Controller
public class UserController {
    @Autowired 
    private UserService service1; // 單例
    
    @Autowired 
    private UserService service2; // 同一個單例
    
    public void checkSingleton() {
        System.out.println(service1 == service2); // 輸出 true
    }
}

關(guān)鍵特性

  • Spring直接管理類的實例化(單例)
  • 不涉及方法調(diào)用攔截
  • 適用于業(yè)務(wù)邏輯組件(Service、Controller等)

場景二:配置類中的@Bean方法調(diào)用

危險示例:在@Component中調(diào)用@Bean方法

@Component // 錯誤用法!
public class DatabaseConfig {
    
    @Bean
    public DataSource dataSource() {
        System.out.println("創(chuàng)建新的DataSource實例");
        return new HikariDataSource(); // 創(chuàng)建連接池
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate() {
        // 直接調(diào)用 → 每次創(chuàng)建新連接池!
        return new JdbcTemplate(dataSource()); 
    }
}

問題所在

當(dāng)Spring調(diào)用jdbcTemplate()方法時:

直接執(zhí)行dataSource()方法

每次調(diào)用都new HikariDataSource() → 創(chuàng)建多個連接池

輸出結(jié)果:

創(chuàng)建新的DataSource實例
創(chuàng)建新的DataSource實例

根本原因

  • @Component類沒有代理機制
  • @Bean方法調(diào)用等同于普通Java方法調(diào)用
  • 導(dǎo)致單例被破壞,資源被重復(fù)創(chuàng)建

安全解決方案

方案一:使用@Configuration代理保護

@Configuration // 關(guān)鍵!
public class CorrectConfig {
    @Bean
    public A a() {
        return new A(b()); // ? 代理確保總返回同一實例
    }
    
    @Bean
    public B b() { 
        System.out.println("創(chuàng)建B實例");
        return new B(); 
    }
}

代理機制

Spring通過CGLIB代理增強@Configuration

單例保護

多次調(diào)用b()返回同一個實例

輸出結(jié)果:

創(chuàng)建B實例 // 僅打印一次

方案二:使用方法參數(shù)注入(推薦)

@Configuration // 或 @Component
public class BestConfig {
    @Bean
    public A a(B b) { // ? 通過參數(shù)注入單例
        return new A(b);
    }
    
    @Bean
    public B b() { return new B(); }
}
  • 最安全的方式
  • 適用于@Configuration和@Component
  • 明確聲明依賴關(guān)系,代碼更清晰

為什么會有這種差異?

1.@Component/@Service類

  • Spring直接管理類的實例化(單例)
  • 不涉及方法調(diào)用攔截
  • 設(shè)計目標(biāo):業(yè)務(wù)組件實現(xiàn)

2.@Configuration類

  • Spring通過CGLIB代理增強類
  • 攔截@Bean方法調(diào)用,確保單例
  • 設(shè)計目標(biāo):Bean定義和配置中心

實際應(yīng)用場景

正確使用@Configuration

@Configuration
public class AppConfig {
    // 全局單例的基礎(chǔ)設(shè)施
    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:mysql://localhost/db");
        return ds;
    }
    
    // 安全調(diào)用其他@Bean方法
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

正確使用@Component

@Service
public class OrderService {
    // 業(yè)務(wù)方法
    public void processOrder(Order order) {
        // 業(yè)務(wù)邏輯...
    }
}

常見錯誤及修復(fù)

錯誤示例

@Component // 錯誤!應(yīng)該用@Configuration
public class PaymentConfig {
    @Bean
    public PaymentService paymentService() {
        // 每次創(chuàng)建新驗證器 → 破壞單例
        return new PaymentService(validator()); 
    }
    
    @Bean
    public Validator validator() { 
        return new PaymentValidator();
    }
}

修復(fù)方案

@Configuration // 修復(fù)方法1:改為@Configuration
public class PaymentConfig {
    @Bean
    public PaymentService paymentService(Validator validator) { // 修復(fù)方法2:參數(shù)注入
        return new PaymentService(validator);
    }
    
    @Bean
    public Validator validator() { 
        return new PaymentValidator();
    }
}

終極總結(jié)

“被@Component或@Service標(biāo)記的類本身默認是單例的,@Autowired注入時不會創(chuàng)建新對象。

但在@Component類內(nèi)部調(diào)用@Bean方法時,會像普通Java方法一樣執(zhí)行,每次調(diào)用都創(chuàng)建新實例。

而@Configuration類通過CGLIB代理,確??鏎Bean方法調(diào)用時始終返回單例。”

這個區(qū)別反映了Spring的兩種不同機制:

  • 組件管理@Component/@Service):處理類實例本身
  • 配置代理@Configuration):處理方法間的調(diào)用關(guān)系

結(jié)語

理解@Configuration@Component的本質(zhì)區(qū)別對于構(gòu)建健壯的Spring應(yīng)用至關(guān)重要。記住以下黃金法則:

  • 配置基礎(chǔ)設(shè)施 → 使用@Configuration
  • 聲明業(yè)務(wù)組件 → 使用@Component/@Service/@Controller
  • 跨Bean依賴 → 總是使用方法參數(shù)注入

面試總結(jié)

"在 @Configuration 類中,所有 @Bean 方法都會CGLIB 代理。當(dāng)在同一個配置類中調(diào)用其他 @Bean 方法時,Spring 會確保始終返回同一個單例實例。而在 @Component 類中,直接調(diào)用 @Bean 方法會像普通 Java 方法一樣執(zhí)行,每次調(diào)用都創(chuàng)建新實例,破壞單例性。

  • @Configuration 用于創(chuàng)建需要全局唯一的基礎(chǔ)設(shè)施(如數(shù)據(jù)庫連接池、線程池)
  • @Component 用于聲明業(yè)務(wù)組件(如Service、Controller), 一般不在@Component中去定義@Bean"

到此這篇關(guān)于揭秘Spring核心注解@Configuration與@Component的本質(zhì)區(qū)別的文章就介紹到這了,更多相關(guān)Spring注解@Configuration與@Component內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 查看JDK安裝路徑,一臺電腦安裝多個版本的JDK并切換使用方式

    查看JDK安裝路徑,一臺電腦安裝多個版本的JDK并切換使用方式

    文章介紹了如何查看JDK安裝路徑以及如何在一臺電腦上安裝和切換多個版本的JDK(JDK?8、JDK?11、JDK?17),內(nèi)容涵蓋了通過命令行查看JDK路徑的方法,以及如何下載、安裝和配置多個JDK版本,并通過修改環(huán)境變量來切換JDK版本
    2025-12-12
  • 集成Spring Redis緩存的實現(xiàn)

    集成Spring Redis緩存的實現(xiàn)

    今天小編就為大家分享一篇關(guān)于集成Spring Redis緩存的實現(xiàn),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Java性能調(diào)優(yōu)概述

    Java性能調(diào)優(yōu)概述

    本文介紹了Java程序性能的主要表現(xiàn)點、衡量程序性能的主要指標(biāo)、性能調(diào)優(yōu)的層次、基本調(diào)優(yōu)策略和手段等,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • 關(guān)于SpringBoot整合redis使用Lettuce客戶端超時問題

    關(guān)于SpringBoot整合redis使用Lettuce客戶端超時問題

    使用到Lettuce連接redis,一段時間后不操作,再去操作redis,會報連接超時錯誤,在其重連后又可使用,糾結(jié)是什么原因?qū)е碌哪?,下面小編給大家?guī)砹薙pringBoot整合redis使用Lettuce客戶端超時問題及解決方案,一起看看吧
    2021-08-08
  • Spring?MVC中的常用注解及用法小結(jié)

    Spring?MVC中的常用注解及用法小結(jié)

    這篇文章主要介紹了Spring?MVC中的常用注解及其用法,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2024-02-02
  • 最新評論

    新兴县| 云阳县| 怀柔区| 上蔡县| 石家庄市| 宜阳县| 鹰潭市| 奉节县| 平遥县| 屏南县| 大安市| 昌吉市| 西和县| 松溪县| 湖口县| 广河县| 封开县| 闻喜县| 利川市| 新郑市| 榆树市| 明星| 将乐县| 武邑县| 孝昌县| 皮山县| 永德县| 夏津县| 阿克陶县| 南充市| 涞水县| 虹口区| 金阳县| 商都县| 尤溪县| 营山县| 静乐县| 弋阳县| 雷山县| 鸡泽县| 淮南市|