欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring核心思想之淺談IoC容器與依賴倒置(DI)

 更新時間:2025年01月20日 11:10:40   作者:Yan.love  
文章介紹了Spring的IoC和DI機(jī)制,以及MyBatis的動態(tài)代理,通過注解和反射,Spring能夠自動管理對象的創(chuàng)建和依賴注入,而MyBatis則通過動態(tài)代理實現(xiàn)了接口方法到數(shù)據(jù)庫操作的映射,文章詳細(xì)解釋了Spring和MyBatis的工作原理,并通過示例代碼展示了它們的結(jié)合使用方式

在日常開發(fā)中,我們總會面臨一個問題:如何優(yōu)雅地管理對象的創(chuàng)建和依賴? 你可能會寫一堆代碼來手動構(gòu)造對象,但這種方式繁瑣且難以維護(hù)。而當(dāng)項目變得復(fù)雜,依賴鏈拉長,手動管理對象的方式很快就會捉襟見肘。

這時,Spring 的 IoC 和 DI 機(jī)制便是解放雙手的利器,它讓開發(fā)者專注于業(yè)務(wù)邏輯,容器則負(fù)責(zé)對象的創(chuàng)建與依賴管理。與此同時,MyBatis 的動態(tài)代理更是省去了為每個接口手動實現(xiàn)類的麻煩,極大地提高了效率。

但你有沒有想過,Spring 是如何找到你的類并自動注入依賴的?MyBatis 又是如何在沒有實現(xiàn)類的情況下完成數(shù)據(jù)庫操作的?如果你也有這些疑問,那恭喜你,今天的內(nèi)容正是為你準(zhǔn)備的!

一、控制反轉(zhuǎn) IoC

控制反轉(zhuǎn)(Inversion of Control, IoC) 是一種設(shè)計思想。它強(qiáng)調(diào)將控制權(quán)從對象本身轉(zhuǎn)移到容器中。服務(wù)中心(容器)負(fù)責(zé)管理各種資源(對象和依賴)。用戶(對象)需要資源時,服務(wù)中心將資源提供給它。容器控制對象的創(chuàng)建、依賴注入和生命周期管理

在傳統(tǒng)編程中,對象需要自己控制依賴的創(chuàng)建和管理;在 IoC 中,這些任務(wù)由容器負(fù)責(zé)。

容器根據(jù) Bean 的依賴關(guān)系,通過 DI 注入所需的依賴。

二、依賴倒置 DI

1. 詳細(xì)概念

依賴注入(Dependency Injection, DI) 是 IoC 的具體實現(xiàn)方式之一。

它通過注入的方式,將對象需要的依賴提供給它,而不是由對象自己去創(chuàng)建,Spring會按需創(chuàng)建相應(yīng)的對象,通過構(gòu)造器、Setter 方法或字段注入,把依賴傳遞給對象。

2. Spring 中 DI 的實現(xiàn)原理

  • 聲明依賴:使用注解(@Component@Service、@Repository)將類標(biāo)記為 Spring 容器管理的 Bean。
  • 注入依賴:Spring 在啟動時掃描類路徑,自動檢測依賴,并通過 @Autowired 注解注入相應(yīng)的Bean。
  • 容器提供依賴:Spring 容器會根據(jù)配置文件或注解,實例化對象并注入到需要的地方。

三、注冊Bean過程:以 Spring+Mybatis 為例

1. Spring 是如何通過注解注冊 Bean 的

Spring 通過 組件掃描(Component Scanning)注解識別 將類注冊為 Bean。

  • 注解識別:包括 @Component@Service、@Repository@Controller 等。
  • 特定集成注解:如 MyBatis 的 @Mapper,它告訴 Spring 將標(biāo)注的接口注冊為 Bean,并交由 MyBatis 動態(tài)代理生成實現(xiàn)類。

注冊過程

  • Spring 啟動時會掃描指定的包路徑。
  • 找到標(biāo)注了這些注解的類或接口,并注冊到 IoC 容器中,形成 Bean 定義。

2. MyBatis是如何動態(tài)生成 UserMapper 的實現(xiàn)類的

UserMapper 是接口,沒有具體實現(xiàn)類。MyBatis 會利用 @Mapper 注解,結(jié)合 Mapper 配置文件或注解中的 SQL 語句,動態(tài)生成代理實現(xiàn)類。

代理類生成過程

動態(tài)代理機(jī)制:MyBatis 使用 JDK 動態(tài)代理,為每個 Mapper 接口生成一個代理類。

InvocationHandler:代理類攔截所有對接口方法的調(diào)用,將它們轉(zhuǎn)發(fā)到 MyBatis 的核心組件(如 SqlSession)執(zhí)行 SQL。

  • 執(zhí)行 SQL:
  • 根據(jù)方法名或注解,定位 SQL 配置。
  • 使用 MyBatis 的 Executor 執(zhí)行 SQL 并返回結(jié)果。

3. @Autowired 注入過程

  • 掃描 Bean:Spring 啟動時,掃描 UserServiceImplUserMapper,分別標(biāo)注了 @Service@Mapper,將它們注冊為 Bean
  • 識別依賴:Spring 在注冊 UserServiceImpl Bean 時,檢測到其字段 userMapper 被標(biāo)注了 @Autowired,即是否依賴于其他 Bean。

注入邏輯

找到目標(biāo) Bean

  • 在 IoC 容器中,根據(jù)類型 UserMapper 查找對應(yīng)的 Bean。
  • 如果找到多個匹配 Bean,Spring 會結(jié)合 Bean 名稱或 @Qualifier 注解解決沖突。

依賴注入

  • Spring 使用 Java 反射機(jī)制為 userMapper 字段賦值。
  • 具體實現(xiàn)偽代碼如下:
// 獲取字段
Field field = UserServiceImpl.class.getDeclaredField("userMapper");
// 使私有字段可訪問
field.setAccessible(true);
// 將找到的 UserMapper Bean 注入到 userServiceImpl 實例
field.set(userServiceImplInstance, userMapperBean);

4. 總結(jié):Spring 與 MyBatis 的結(jié)合

Spring

  • 提供 IoC 容器,掃描 Bean,處理依賴注入。
  • 通過反射將 UserMapper 動態(tài)代理對象注入到 UserServiceImpl。

MyBatis

  • 動態(tài)生成 UserMapper 的代理實現(xiàn)類,負(fù)責(zé)將方法調(diào)用轉(zhuǎn)化為 SQL 查詢。
  • 代理類中通過 InvocationHandler 將方法調(diào)用委托給 MyBatis 的 SQL 執(zhí)行器。

附加:代理類與 UserMapper 實現(xiàn)類的差異

代理類

  • 動態(tài)生成,沒有手寫實現(xiàn)代碼。
  • 通過攔截接口方法,轉(zhuǎn)發(fā)到 MyBatis 核心組件處理。

普通實現(xiàn)類

  • 靜態(tài)定義,需手動實現(xiàn)每個方法的邏輯。

示例對比

// 動態(tài)代理生成的代理類示例
public class UserMapperProxy implements UserMapper {
    private final SqlSession sqlSession;
?
    public UserMapperProxy(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }
?
    @Override
    public User findById(int id) {
        // 將方法調(diào)用轉(zhuǎn)化為 MyBatis 的 SQL 執(zhí)行
        return sqlSession.selectOne("namespace.findById", id);
    }
}
?
// 普通實現(xiàn)類(手動實現(xiàn))
public class UserMapperImpl implements UserMapper {
    @Override
    public User findById(int id) {
        // 自己寫邏輯,連接數(shù)據(jù)庫,執(zhí)行 SQL
        return executeSQL("SELECT * FROM user WHERE id = ?", id);
    }
}

動態(tài)代理的優(yōu)勢在于:

  • 代碼復(fù)用性高:只需定義接口和 SQL,無需重復(fù)寫實現(xiàn)類。
  • 與 SQL 配置無縫對接:方便維護(hù)和管理 SQL 語句。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java實現(xiàn)基于SGIP協(xié)議開發(fā)聯(lián)通短信的方法

    java實現(xiàn)基于SGIP協(xié)議開發(fā)聯(lián)通短信的方法

    這篇文章主要介紹了java實現(xiàn)基于SGIP協(xié)議開發(fā)聯(lián)通短信的方法,涉及java短信發(fā)送的相關(guān)實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • Java?Optional用法面試題精講

    Java?Optional用法面試題精講

    這篇文章主要為大家介紹了Java?Optional用法面試題精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Spring-AOP自動創(chuàng)建代理之BeanNameAutoProxyCreator實例

    Spring-AOP自動創(chuàng)建代理之BeanNameAutoProxyCreator實例

    這篇文章主要介紹了Spring-AOP自動創(chuàng)建代理之BeanNameAutoProxyCreator實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java.lang.Void 與 void的比較及使用方法介紹

    java.lang.Void 與 void的比較及使用方法介紹

    這篇文章主要介紹了java.lang.Void 與 void的比較及使用方法介紹,小編覺得挺不錯的,這里給大家分享一下,需要的朋友可以參考。
    2017-10-10
  • 使用Java8?Stream流的skip?+?limit實現(xiàn)批處理的方法

    使用Java8?Stream流的skip?+?limit實現(xiàn)批處理的方法

    Stream 作為 Java 8 的一大亮點(diǎn),它與 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念這篇文章主要介紹了使用Java8?Stream流的skip?+?limit實現(xiàn)批處理,需要的朋友可以參考下
    2022-07-07
  • 使用Java進(jìn)行驗證郵箱是否有用

    使用Java進(jìn)行驗證郵箱是否有用

    在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用中,郵箱驗證是一個常見的需求,本文將詳細(xì)介紹如何使用Java實現(xiàn)郵箱驗證功能,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01
  • 淺談Spring裝配Bean之組件掃描和自動裝配

    淺談Spring裝配Bean之組件掃描和自動裝配

    本篇文章主要介紹了淺談Spring裝配Bean之組件掃描和自動裝配,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • java 反射getClass .class 的使用方法示例

    java 反射getClass .class 的使用方法示例

    這篇文章主要介紹了java 反射getClass .class 的使用方法,結(jié)合實例形式分析了java類反射機(jī)制的相關(guān)操作技巧,需要的朋友可以參考下
    2019-11-11
  • Springboot引入多個yml方法(多種方案)

    Springboot引入多個yml方法(多種方案)

    SpringBoot默認(rèn)加載的是application.yml文件,所以想要引入其他配置的yml文件,就要在application.yml中激活該文件這篇文章主要介紹了Springboot引入多個yml方法,需要的朋友可以參考下
    2019-10-10
  • Mybatis order by 動態(tài)傳參出現(xiàn)的問題及解決方法

    Mybatis order by 動態(tài)傳參出現(xiàn)的問題及解決方法

    今天,我正在愉快地CRUD,突然發(fā)現(xiàn)出現(xiàn)一個Bug,我們來看看是怎么回事吧!接下來通過本文給大家介紹Mybatis order by 動態(tài)傳參出現(xiàn)的一個小bug,需要的朋友可以參考下
    2021-07-07

最新評論