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

源碼分析:Spring IOC 容器初始化過(guò)程

開(kāi)發(fā)
本文我們通過(guò)源碼深度分析了 Spring 5.x IOC容器的啟動(dòng)流程,IOC是 Spring的核心,也是比較難懂的一部分,。?

這篇文章,我們將通過(guò)剖析 Spring 5.x源碼,深度分析 IOC 容器的初始化過(guò)程。

一、IOC 的基本概念

IOC,全稱(chēng)Inversion of Control,翻譯為,它是一種設(shè)計(jì)原則,旨在通過(guò)減少對(duì)象之間的耦合度,提高系統(tǒng)的靈活性和可維護(hù)性。在傳統(tǒng)的編程方式中,對(duì)象通常負(fù)責(zé)自己依賴(lài)的創(chuàng)建和管理,這導(dǎo)致了高耦合度。而在 IOC 模式下,對(duì)象的創(chuàng)建和依賴(lài)管理交由外部容器控制,實(shí)現(xiàn)了對(duì)象之間的松耦合。

Spring 的 IOC 容器負(fù)責(zé)管理應(yīng)用程序中的對(duì)象及其依賴(lài)關(guān)系。它通過(guò)配置元數(shù)據(jù)(如 XML、注解、Java 配置類(lèi)等)來(lái)描述對(duì)象的創(chuàng)建、裝配和管理過(guò)程。IOC 容器在應(yīng)用啟動(dòng)時(shí),根據(jù)配置元數(shù)據(jù)創(chuàng)建和裝配所有的 Bean,從而實(shí)現(xiàn)應(yīng)用程序的依賴(lài)注入。

IOC 容器的核心接口包括:

  • BeanFactory:是 Spring IOC 容器的最基本接口,提供了獲取 Bean 的基本功能。它延遲加載 Bean,即在第一次調(diào)用 getBean 方法時(shí)才創(chuàng)建 Bean。
  • ApplicationContext:繼承自 BeanFactory,提供了更高級(jí)的功能,如國(guó)際化支持、事件傳播、AOP 集成等。ApplicationContext 通常在企業(yè)級(jí)應(yīng)用中使用更為廣泛。

二、Spring IOC初始化流程

Spring 5.x 在 IOC 容器的初始化過(guò)程中,涵蓋了配置解析、Bean 定義加載與注冊(cè)、Bean 的實(shí)例化與裝配、初始化以及后期處理等多個(gè)階段。以下將對(duì)這些階段進(jìn)行詳細(xì)解析。

1. 配置元數(shù)據(jù)的解析

在 Spring 應(yīng)用中,配置元數(shù)據(jù)描述了應(yīng)用中各個(gè) Bean 及其依賴(lài)關(guān)系。配置元數(shù)據(jù)可以通過(guò)多種方式提供,包括 XML 配置文件、注解以及 Java 配置類(lèi)(基于 @Configuration 的類(lèi))。

(1) XML 配置

傳統(tǒng)的 Spring 配置方式,通過(guò) XML 文件定義 Bean 及其依賴(lài)關(guān)系。Spring 通過(guò) XmlBeanDefinitionReader 將 XML 文件解析為 BeanDefinition 對(duì)象,并注冊(cè)到 BeanFactory 中。

示例 XML 配置:

<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myBean" class="com.yuanjava.MyBean">
        <property name="dependency" ref="myDependency"/>
    </bean>

    <bean id="myDependency" class="com.yuanjava.MyDependency"/>
</beans>

(2) 注解配置

Spring 提供了多種注解,用于定義 Bean 和管理依賴(lài)關(guān)系,如 @Component、@Service、@Repository、@Controller、@Configuration 以及 @Autowired 等。通過(guò) ComponentScan 掃描包路徑,容器自動(dòng)檢測(cè)和注冊(cè)帶有特定注解的類(lèi)為 Bean。

示例注解配置:

@Component
public class MyBean {
    @Autowired
    private MyDependency myDependency;
}

@Component
public class MyDependency { }

(3) Java 配置

基于 Java 的配置方式,通過(guò) @Configuration 注解的類(lèi),使用 @Bean 方法定義 Bean。這種方式結(jié)合了類(lèi)型安全和靈活性,受到越來(lái)越多開(kāi)發(fā)者的青睞。

示例 Java 配置:

@Configuration
public class AppConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean(myDependency());
    }

    @Bean
    public MyDependency myDependency() {
        return new MyDependency();
    }
}

2. Bean 定義的加載與注冊(cè)

配置元數(shù)據(jù)被解析后,Spring IOC 容器需要將其轉(zhuǎn)化為內(nèi)部的 BeanDefinition 對(duì)象,并注冊(cè)到 BeanFactory 中。BeanDefinition 包含了 Bean 的類(lèi)名、作用域、初始化方法、銷(xiāo)毀方法、依賴(lài)關(guān)系等信息。

在 Spring 5.x 中,具體步驟通常如下:

  • 創(chuàng)建 BeanFactory 實(shí)例:常用的實(shí)現(xiàn)類(lèi)是 DefaultListableBeanFactory。
  • 使用 BeanDefinitionReader 讀取配置:如 XmlBeanDefinitionReader、AnnotatedBeanDefinitionReader、ConfigurationClassPostProcessor 等。
  • **解析并注冊(cè) BeanDefinition**:將解析后的 Bean 定義注冊(cè)到 BeanFactory 中。

示例代碼:

// 創(chuàng)建 BeanFactory 實(shí)例
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

// 創(chuàng)建 BeanDefinitionReader
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);

// 加載 XML 配置文件
reader.loadBeanDefinitions("classpath:applicationContext.xml");

// 或者使用注解配置
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

3. Bean 的實(shí)例化與裝配

在 Bean 定義加載并注冊(cè)后,IOC 容器根據(jù)需要實(shí)例化 Bean,并完成屬性的注入與依賴(lài)的裝配。Spring 提供了多種方式來(lái)完成 Bean 的實(shí)例化與裝配,如構(gòu)造函數(shù)注入、Setter 方法注入、注解注入等。

(1) 實(shí)例化策略

Spring 提供了多種 Bean 的實(shí)例化策略,包括:

  • 通過(guò)無(wú)參構(gòu)造函數(shù)實(shí)例化:默認(rèn)的實(shí)例化方式。
  • 通過(guò)工廠(chǎng)方法實(shí)例化:可以通過(guò)靜態(tài)工廠(chǎng)方法或?qū)嵗S(chǎng)方法來(lái)創(chuàng)建 Bean。
  • 通過(guò)構(gòu)造函數(shù)參數(shù)實(shí)例化:支持通過(guò)構(gòu)造函數(shù)參數(shù)傳遞依賴(lài)。

(2) 依賴(lài)注入方式

依賴(lài)注入分為兩種主要方式:

  • 構(gòu)造函數(shù)注入:通過(guò)構(gòu)造函數(shù)傳遞依賴(lài)對(duì)象。
public class MyBean {
    private final MyDependency myDependency;

    public MyBean(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}
  • Setter 方法注入:通過(guò) Setter 方法注入依賴(lài)對(duì)象。
public class MyBean {
  private MyDependency myDependency;

  @Autowired
  public void setMyDependency(MyDependency myDependency) {
      this.myDependency = myDependency;
  }
}

在 Spring 5.x 中,推薦使用構(gòu)造函數(shù)注入,因?yàn)樗喜豢勺儗?duì)象的設(shè)計(jì)理念,且有利于編寫(xiě)可測(cè)試的代碼。

(3) 自動(dòng)裝配

Spring 支持自動(dòng)裝配,減少了顯式配置的工作量。自動(dòng)裝配有以下幾種模式:

  • 按類(lèi)型自動(dòng)裝配 (@Autowired):根據(jù) Bean 的類(lèi)型進(jìn)行裝配。
  • 按名稱(chēng)自動(dòng)裝配 (@Qualifier):結(jié)合 @Qualifier 注解指定 Bean 的名稱(chēng)。
  • 基于 Java 注解的裝配:如 @Primary、@Resource 等。
  • 基于構(gòu)造函數(shù)的自動(dòng)裝配:通過(guò)構(gòu)造函數(shù)參數(shù)進(jìn)行裝配。

示例代碼:

@Component
public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}

4. Bean 的初始化

在 Bean 被實(shí)例化并裝配完成后,還需要進(jìn)行初始化工作。初始化過(guò)程包括執(zhí)行自定義的初始化方法、BeanPostProcessor 的前置和后置處理等。

(1) InitializingBean 接口

Bean 可以通過(guò)實(shí)現(xiàn) InitializingBean 接口,重寫(xiě) afterPropertiesSet 方法來(lái)自定義初始化邏輯。

public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        // 初始化邏輯
    }
}

(2) 自定義初始化方法

在 Bean 配置中,可以通過(guò) init-method 屬性指定自定義的初始化方法。

<bean id="myBean" class="com.yuanjava.MyBean" init-method="init"/>

或者通過(guò)注解 @PostConstruct 指定初始化方法:

public class MyBean {
    @PostConstruct
    public void init() {
        // 初始化邏輯
    }
}

(3) BeanPostProcessor

BeanPostProcessor 是 Spring 提供的擴(kuò)展點(diǎn),允許在 Bean 初始化前后進(jìn)行自定義處理。常見(jiàn)的實(shí)現(xiàn)類(lèi)有 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、ProxyPostProcessor 等。

BeanPostProcessor 提供兩個(gè)主要方法:

  • postProcessBeforeInitialization:在 Bean 初始化方法調(diào)用前執(zhí)行。
  • postProcessAfterInitialization:在 Bean 初始化方法調(diào)用后執(zhí)行。

示例代碼:

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 初始化前處理
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 初始化后處理
        return bean;
    }
}

5. Bean 的后處理與銷(xiāo)毀

Bean 的生命周期不僅包括初始化,還包括銷(xiāo)毀過(guò)程。Spring 提供了多種機(jī)制來(lái)處理 Bean 的銷(xiāo)毀,如實(shí)現(xiàn) DisposableBean 接口、指定銷(xiāo)毀方法、使用 @PreDestroy 注解等。

(1) DisposableBean 接口

通過(guò)實(shí)現(xiàn) DisposableBean 接口,Bean 可以在銷(xiāo)毀前執(zhí)行特定的邏輯。

public class MyBean implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        // 銷(xiāo)毀邏輯
    }
}

(2) 自定義銷(xiāo)毀方法

在 Bean 配置中,可以通過(guò) destroy-method 屬性指定自定義的銷(xiāo)毀方法。

<bean id="myBean" class="com.yuanjava.MyBean" destroy-method="cleanup"/>

或者使用 @PreDestroy 注解指定銷(xiāo)毀方法:

public class MyBean {
    @PreDestroy
    public void cleanup() {
        // 銷(xiāo)毀邏輯
    }
}

(3) DisposableBean 與 destroy-method 的優(yōu)先級(jí)

當(dāng) Bean 同時(shí)實(shí)現(xiàn)了 DisposableBean 接口并指定了 destroy-method 時(shí),Spring 會(huì)按照以下順序執(zhí)行銷(xiāo)毀邏輯:

  • 執(zhí)行實(shí)現(xiàn)的 DisposableBean 接口的 destroy 方法。
  • 執(zhí)行 destroy-method 指定的方法。

這種方法確保了銷(xiāo)毀邏輯的有序執(zhí)行,且用戶(hù)可以通過(guò)合理配置完成自定義的銷(xiāo)毀操作。

三、關(guān)鍵類(lèi)與組件

在 Spring 5.x 中,IOC 容器的初始化過(guò)程涉及到多個(gè)關(guān)鍵類(lèi)和組件,這些類(lèi)和組件各司其職,共同完成容器的初始化與管理工作。以下將介紹其中幾個(gè)重要的類(lèi)和組件。

1. ApplicationContext 接口及其實(shí)現(xiàn)

ApplicationContext 是 Spring IOC 容器的核心接口,繼承自 BeanFactory,提供了更強(qiáng)大的功能。常見(jiàn)的實(shí)現(xiàn)類(lèi)包括:

  • ClassPathXmlApplicationContext:基于類(lèi)路徑的 XML 配置文件創(chuàng)建 ApplicationContext。
  • FileSystemXmlApplicationContext:基于文件系統(tǒng)的 XML 配置文件創(chuàng)建 ApplicationContext。
  • AnnotationConfigApplicationContext:基于 Java 注解的配置類(lèi)創(chuàng)建 ApplicationContext。
  • GenericWebApplicationContext:適用于 Web 應(yīng)用的泛化 ApplicationContext。

示例代碼:

// 基于 XML 配置
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

// 基于注解配置
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

2. DefaultListableBeanFactory

DefaultListableBeanFactory 是 BeanFactory 的默認(rèn)實(shí)現(xiàn),也是最常用的實(shí)現(xiàn)類(lèi)之一。它支持 Bean 的定義注冊(cè)、依賴(lài)注入、Bean 后處理、作用域管理等功能。

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

3. BeanDefinition 與 BeanDefinitionReader

BeanDefinition 是 Spring 內(nèi)部用于描述 Bean 的核心類(lèi),包含了 Bean 的類(lèi)名、作用域、依賴(lài)關(guān)系、初始化方法等信息。

BeanDefinitionReader 是用于讀取不同格式的配置元數(shù)據(jù)并注冊(cè)到 BeanFactory 中的接口,常見(jiàn)的實(shí)現(xiàn)類(lèi)有:

  • XmlBeanDefinitionReader:讀取 XML 配置文件。
  • AnnotatedBeanDefinitionReader:讀取基于注解的配置。
  • PropertiesBeanDefinitionReader:讀取基于 properties 文件的配置。

示例代碼:

// 創(chuàng)建 BeanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

// 創(chuàng)建 XML BeanDefinitionReader
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);

// 加載 XML 配置
reader.loadBeanDefinitions("classpath:applicationContext.xml");

4. InstantiationStrategy

InstantiationStrategy 接口定義了 Bean 實(shí)例化的策略。Spring 提供了兩種默認(rèn)的實(shí)現(xiàn):

  • SimpleInstantiationStrategy:簡(jiǎn)單的實(shí)例化策略,適用于多數(shù)場(chǎng)景。
  • CglibSubclassingInstantiationStrategy:使用 CGLIB 生成子類(lèi)進(jìn)行實(shí)例化,常用于需要 AOP 代理的 Bean。
InstantiationStrategy strategy = new SimpleInstantiationStrategy();

5. AutowireCapableBeanFactory

AutowireCapableBeanFactory 是 BeanFactory 的子接口,提供了更高級(jí)別的功能,如支持自動(dòng)裝配、Bean 后處理等。它在 Spring 的自動(dòng)裝配和后處理機(jī)制中起到了關(guān)鍵作用。

AutowireCapableBeanFactory autowireCapableBeanFactory = context.getAutowireCapableBeanFactory();

6. BeanPostProcessor

BeanPostProcessor 是 Spring 提供的擴(kuò)展點(diǎn),用于在 Bean 的初始化前后進(jìn)行自定義處理。常用的實(shí)現(xiàn)類(lèi)包括:

  • AutowiredAnnotationBeanPostProcessor:處理 @Autowired 注解的裝配。
  • CommonAnnotationBeanPostProcessor:處理 @PostConstruct 和 @PreDestroy 注解。
  • ProxyPostProcessor:用于生成 AOP 代理等。
public class MyCustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 自定義前置處理
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 自定義后置處理
        return bean;
    }
}

四、總結(jié)

本文,我們通過(guò)源碼深度分析了 Spring 5.x IOC容器的啟動(dòng)流程,IOC是 Spring的核心,也是比較難懂的一部分,建議可以多去閱讀 Spring源碼,了解其精髓。

責(zé)任編輯:趙寧寧 來(lái)源: 猿java
相關(guān)推薦

2023-05-03 23:48:24

Spring容器初始化

2020-12-03 09:50:52

容器IoC流程

2024-01-15 06:34:09

Gin鏡像容器

2012-03-13 13:38:42

Java

2021-03-12 10:30:11

SpringMVC流程初始化

2022-07-06 10:37:45

SpringServlet初始化

2009-06-04 09:26:51

struts 源碼struts 資源文件

2021-07-07 05:00:17

初始化源碼

2023-08-28 07:25:58

DDE服務(wù)器管理器

2009-09-17 16:06:22

C#數(shù)組初始化

2022-01-26 11:00:58

源碼層面Vue3

2009-06-22 10:20:01

Spring IoC容

2023-10-06 20:57:52

C++聚合成員

2012-04-09 13:43:12

Java

2023-11-12 23:08:17

C++初始化

2022-12-07 08:02:43

Spring流程IOC

2024-10-29 11:27:27

2023-07-13 09:13:18

Docker容器

2021-12-02 15:08:23

鴻蒙HarmonyOS應(yīng)用

2024-10-18 11:32:15

點(diǎn)贊
收藏

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