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

Spring依賴注入底層原理詳解

 更新時(shí)間:2023年09月14日 08:58:04   作者:這堆干貨有點(diǎn)猛  
這篇文章主要介紹了Spring依賴注入底層原理詳解,??依賴注入是一種設(shè)計(jì)模式,它將對(duì)象之間的依賴關(guān)系從代碼中移除,并由容器來管理這些依賴關(guān)系,依賴注入的主要目的是降低代碼的耦合度,使代碼更加靈活和可維護(hù),需要的朋友可以參考下

Spring 框架作為 Java 開發(fā)中最流行的框架之一,其核心特性之一就是依賴注入(Dependency Injection,DI)。

在Spring中,依賴注入是通過 IOC 容器(Inversion of Control,控制反轉(zhuǎn))來實(shí)現(xiàn)的。

本文將詳細(xì)介紹Spring的依賴注入底層原理,并提供源碼示例。

什么是依賴注入

依賴注入是一種設(shè)計(jì)模式,它將對(duì)象之間的依賴關(guān)系從代碼中移除,并由容器來管理這些依賴關(guān)系。依賴注入的主要目的是降低代碼的耦合度,使代碼更加靈活和可維護(hù)。

在 Java 中,依賴通常是通過構(gòu)造函數(shù)或者 Setter 方法來注入的。使用依賴注入,我們可以將對(duì)象的創(chuàng)建和依賴關(guān)系的管理分離開來,從而使得代碼更加容易測(cè)試和維護(hù)。

實(shí)現(xiàn)原理

Spring的依賴注入是通過 IOC 容器來實(shí)現(xiàn)的。在Spring中,IOC 容器負(fù)責(zé)創(chuàng)建和管理對(duì)象,以及管理對(duì)象之間的依賴關(guān)系。

IOC 容器

IOC 容器是指用于管理對(duì)象和依賴關(guān)系的容器。Spring提供了多種 IOC 容器實(shí)現(xiàn),包括 BeanFactory 和 ApplicationContext 等。

BeanFactory 是 Spring 中最基本的 IOC 容器,它提供了基本的 IOC 功能。

ApplicationContext 則是BeanFactory的擴(kuò)展,它提供了更多的功能,如事件發(fā)布、國(guó)際化支持、AOP等。

在 Spring 中,BeanFactory 和 ApplicationContext 都是通過反射來實(shí)例化對(duì)象,并通過依賴注入來管理對(duì)象之間的依賴關(guān)系。

Bean定義

在 Spring 中,每個(gè)被管理的對(duì)象都需要有一個(gè)對(duì)應(yīng)的 Bean 定義。Bean定義是一個(gè)元數(shù)據(jù),它描述了一個(gè) Bean 的類型、屬性、依賴關(guān)系等信息。

Bean 定義通常是通過XML配置文件、 Java 配置類或者注解來定義的。下面是一個(gè)使用 XML 配置文件定義 Bean 的示例:

<bean id="userService" class="com.example.UserService">
    <property name="userRepository" ref="userRepository"/>
</bean>
<bean id="userRepository" class="com.example.UserRepositoryImpl"/>

在上面的示例中,我們定義了一個(gè)名為 userService的Bean,它的類型是com.example.UserService。它依賴于另一個(gè)名為userRepository的Bean,類型是com.example.UserRepositoryImpl。

依賴注入

在 Spring 中,依賴注入是通過反射來實(shí)現(xiàn)的。當(dāng) IOC 容器創(chuàng)建 Bean 時(shí),它會(huì)檢查 Bean 定義中所聲明的依賴關(guān)系,并嘗試通過反射來注入這些依賴關(guān)系。

依賴注入通常分為三種方式:構(gòu)造函數(shù)注入、Setter 方法注入和字段注入。

構(gòu)造函數(shù)注入

構(gòu)造函數(shù)注入是最常見的依賴注入方式。在 Spring 中,我們可以通過構(gòu)造函數(shù)來注入 Bean 的依賴關(guān)系。當(dāng) IOC 容器創(chuàng)建 Bean 時(shí),它會(huì)檢查 Bean 定義中所聲明的構(gòu)造函數(shù),并嘗試通過反射來調(diào)用這個(gè)構(gòu)造函數(shù),并將依賴關(guān)系作為參數(shù)傳遞進(jìn)去。

下面是一個(gè)使用構(gòu)造函數(shù)注入的示例:

public class UserService {
    private final UserRepository userRepository;
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    // ...
}

在上面的示例中,我們定義了一個(gè) UserService 類,并將 UserRepository 依賴關(guān)系通過構(gòu)造函數(shù)注入進(jìn)去。

Setter方法注入

Setter 方法注入是另一種常見的依賴注入方式。我們可以通過 Setter 方法來注入Bean的依賴關(guān)系。當(dāng) IOC 容器創(chuàng)建Bean時(shí),它會(huì)檢查 Bean 定義中所聲明的 Setter 方法,并嘗試通過反射來調(diào)用這個(gè) Setter 方法,并將依賴關(guān)系作為參數(shù)傳遞進(jìn)去。

下面是一個(gè)使用Setter方法注入的示例:

public class UserService {
    private UserRepository userRepository;
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    // ...
}

在上面的示例中,我們定義了一個(gè) UserService 類,并將 UserRepository 依賴關(guān)系通過 Setter 方法注入進(jìn)去。

字段注入

字段注入是一種不太常見的依賴注入方式。我們可以通過字段來注入Bean的依賴關(guān)系。當(dāng) IOC 容器創(chuàng)建 Bean 時(shí),它會(huì)嘗試通過反射來注入這些字段。

下面是一個(gè)使用字段注入的示例:

public class UserService {
    @Autowired
    private UserRepository userRepository;
    // ...
}

在上面的示例中,我們使用了 @Autowired 注解來將 UserRepository 依賴關(guān)系注入到 userService 對(duì)象中的 userRepository 字段中。

生命周期回調(diào)

在Spring中,Bean生命周期包括四個(gè)階段:實(shí)例化、屬性賦值、初始化、銷毀。在這些階段中,Spring 提供了多個(gè)回調(diào)方法,以便我們?cè)?Bean 的生命周期中進(jìn)行一些自定義操作。

下面是一些常用的Bean生命周期回調(diào)方法:

  • 實(shí)例化:Bean 實(shí)例化之后,Spring 會(huì)調(diào)用 BeanPostProcessor 的 postProcessBeforeInitialization 方法。
  • 屬性賦值:在Bean實(shí)例化之后,Spring 會(huì)將 Bean 定義中所聲明的屬性值賦值給 Bean 對(duì)象。
  • 初始化:在 Bean 屬性賦值之后,Spring 會(huì)調(diào)用 InitializingBeanafterPropertiesSet 方法或者 @Bean 注解的 initMethod 方法。
  • 銷毀:在 IOC 容器關(guān)閉時(shí),Spring 會(huì)調(diào)用 DisposableBean 的 destroy 方法或者 @Bean 注解的 destroyMethod方 法。

下面是一個(gè)實(shí)現(xiàn) InitializingBean 和 DisposableBean 接口的示例:

public class UserService implements InitializingBean, DisposableBean {
    private UserRepository userRepository;
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public void afterPropertiesSet() throws Exception {
        // 在Bean屬性賦值之后,執(zhí)行一些初始化操作
    }
    public void destroy() throws Exception {
        // 在 IOC 容器關(guān)閉時(shí),執(zhí)行一些銷毀操作
    }
    // ...
}

注解

在 Spring 中,我們可以使用注解來簡(jiǎn)化 Bean 定義和依賴注入的過程。Spring 提供了多個(gè)注解來實(shí)現(xiàn)依賴注入和生命周期回調(diào)等功能。

下面是一些常用的 Spring 注解:

  • @Component:用于標(biāo)記一個(gè)類為 Bean。
  • @Autowired:用于標(biāo)記一個(gè)字段、構(gòu)造函數(shù)或者 Setter 方法需要進(jìn)行依賴注入。
  • @Qualifier:當(dāng)存在多個(gè)相同類型的 Bean 時(shí),用于指定依賴注入的具體實(shí)現(xiàn)。
  • @Value:用于注入一個(gè)常量值。
  • @PostConstruct:用于標(biāo)記一個(gè)方法為 Bean 初始化方法。
  • @PreDestroy:用于標(biāo)記一個(gè)方法為 Bean 銷毀方法。

下面是一個(gè)使用注解的示例:

@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;
    @PostConstruct
    public void init() {
        // 在Bean屬性賦值之后,執(zhí)行一些初始化操作
    }
    @PreDestroy
    public void destroy() {
        // 在 IOC 容器關(guān)閉時(shí),執(zhí)行一些銷毀操作
    }
    // ...
}

源碼示例

下面是一個(gè)使用Spring的依賴注入功能的示例:

@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;
    public void save(User user) {
        userRepository.save(user);
    }
}
@Component
public class UserRepositoryImpl implements UserRepository {
    public void save(User user) {
        // 保存用戶信息
    }
}
@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }
    @Bean
    public UserRepository userRepository() {
        return new UserRepositoryImpl();
    }
}
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = context.getBean(UserService.class);
        User user = new User();
        userService.save(user);
    }
}

在上面的示例中,我們使用了 @Component 注解標(biāo)記了 UserService 和 UserRepositoryImpl 兩個(gè)類為 Bean。在 AppConfig 類中,我們使用 @Bean 注解來定義了 UserRepository 和 UserService 兩個(gè) Bean。

在 Main 類中,我們使用 AnnotationConfigApplicationContext 來創(chuàng)建 IOC 容器,并通過依賴注入來獲取 UserService 對(duì)象,并調(diào)用它的 save 方法。

總結(jié)

本文詳細(xì)介紹了 Spring 的依賴注入底層原理,并提供了源碼示例。

通過本文的學(xué)習(xí),我們可以更好地理解 Spring 的依賴注入機(jī)制,以及如何在實(shí)際開發(fā)中使用它來降低代碼的耦合度,使代碼更加靈活和可維護(hù)。

到此這篇關(guān)于Spring依賴注入底層原理詳解的文章就介紹到這了,更多相關(guān)Spring依賴注入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis模糊查詢like語句該如何寫

    mybatis模糊查詢like語句該如何寫

    MyBatis模糊查詢通常使用LIKE關(guān)鍵字,結(jié)合concat函數(shù)拼接通配符%實(shí)現(xiàn),在MyBatis配置文件中,通過#{keyword}傳遞參數(shù),生成帶有通配符的查詢語句,MyBatis-Plus中,通過LambdaQueryWrapper類和like方法構(gòu)建模糊查詢條件,簡(jiǎn)化查詢操作
    2024-09-09
  • Idea上傳、拉取、更新項(xiàng)目到gitee的實(shí)現(xiàn)

    Idea上傳、拉取、更新項(xiàng)目到gitee的實(shí)現(xiàn)

    該文章介紹了將Idea項(xiàng)目上傳至Gitee的步驟,包括創(chuàng)建本地倉(cāng)庫(kù)、添加到緩沖區(qū)、提交到本地倉(cāng)庫(kù)、推送至遠(yuǎn)程倉(cāng)庫(kù)等以及從Gitee拉取項(xiàng)目的方法,整個(gè)過程涉及到創(chuàng)建遠(yuǎn)程倉(cāng)庫(kù)、項(xiàng)目上傳、更新項(xiàng)目等和提交等內(nèi)容
    2026-04-04
  • Springboot中redis使用lettuce連接池經(jīng)常連接超時(shí)問題分析及解決

    Springboot中redis使用lettuce連接池經(jīng)常連接超時(shí)問題分析及解決

    文章主要介紹了在Spring?Boot項(xiàng)目中,使用Lettuce作為Redis客戶端時(shí)遇到的問題——連接在一段時(shí)間后會(huì)自動(dòng)掉線,問題的根源在于Lettuce的空閑連接處理機(jī)制,文章提供了Spring?Boot?2.3及以上版本的解決方案,即通過配置解決,或者排除Lettuce并采用Jedis
    2025-11-11
  • SpringBoot設(shè)置接口超時(shí)的方法小結(jié)

    SpringBoot設(shè)置接口超時(shí)的方法小結(jié)

    這篇文章主要介紹了SpringBoot設(shè)置接口超時(shí)的方法小結(jié),包括配置文件,config配置類及相關(guān)示例代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Java中JS引擎實(shí)現(xiàn)的一句話木馬

    Java中JS引擎實(shí)現(xiàn)的一句話木馬

    這篇文章主要為大家介紹了如何利用Java中JS引擎實(shí)現(xiàn)的一句話木馬,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步
    2022-02-02
  • SpringMvc/SpringBoot HTTP通信加解密的實(shí)現(xiàn)

    SpringMvc/SpringBoot HTTP通信加解密的實(shí)現(xiàn)

    這篇文章主要介紹了SpringMvc/SpringBoot HTTP通信加解密的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • idea導(dǎo)入項(xiàng)目框架的詳細(xì)操作方法

    idea導(dǎo)入項(xiàng)目框架的詳細(xì)操作方法

    大家使用idea開發(fā)工具時(shí)經(jīng)常會(huì)需要導(dǎo)入項(xiàng)目框架,糾結(jié)該怎么操作呢,今天小編給大家分享一篇圖文教程,幫助大家解決idea導(dǎo)入項(xiàng)目框架的問題,感興趣的朋友一起看看吧
    2021-05-05
  • 使用spring的restTemplate注意點(diǎn)

    使用spring的restTemplate注意點(diǎn)

    這篇文章主要介紹了使用spring的restTemplate注意點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 如何使用JaCoCo分析java單元測(cè)試覆蓋率

    如何使用JaCoCo分析java單元測(cè)試覆蓋率

    在做單元測(cè)試時(shí),代碼覆蓋率常常被拿來作為衡量測(cè)試好壞的指標(biāo),甚至,用代碼覆蓋率來考核測(cè)試任務(wù)完成情況,比如,代碼覆蓋率必須達(dá)到80%或 90%。于是乎,測(cè)試人員費(fèi)盡心思設(shè)計(jì)案例覆蓋代碼。下面我們來學(xué)習(xí)一下吧
    2019-06-06
  • Java實(shí)戰(zhàn)之敏感詞過濾器

    Java實(shí)戰(zhàn)之敏感詞過濾器

    這篇文章主要介紹了Java實(shí)戰(zhàn)之敏感詞過濾器,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04

最新評(píng)論

滕州市| 岫岩| 美姑县| 鄂温| 邻水| 岱山县| 阿巴嘎旗| 宾川县| 肇庆市| 吴桥县| 河南省| 哈密市| 调兵山市| 梧州市| 宾川县| 揭西县| 普洱| 朝阳县| 民乐县| 米林县| 仲巴县| 昂仁县| 友谊县| 平潭县| 定兴县| 久治县| 万全县| 彭山县| 高安市| 定远县| 交口县| 洛川县| 潍坊市| 黄龙县| 海盐县| 和林格尔县| 泰兴市| 伊金霍洛旗| 舞钢市| 鹤岗市| 京山县|