必知必会的13个Bean生命周期处理机制:深入理解与实践

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 【10月更文挑战第15天】在Spring框架中,Bean的生命周期是一个至关重要的概念,它涵盖了从Bean的创建、初始化、使用到销毁的全过程。对于一名资深的架构师而言,深入理解和掌握Bean生命周期的每一个处理机制,是构建健壮、高效和可维护应用程序的基础。本文将详细介绍Bean生命周期的13个处理机制,并通过实战demo示例来加深理解。

背景

在Spring框架中,Bean的生命周期是一个至关重要的概念,它涵盖了从Bean的创建、初始化、使用到销毁的全过程。对于一名资深的架构师而言,深入理解和掌握Bean生命周期的每一个处理机制,是构建健壮、高效和可维护应用程序的基础。本文将详细介绍Bean生命周期的13个处理机制,并通过实战demo示例来加深理解。

1. Bean元信息配置阶段

背景与应用场景

Bean元信息配置阶段是Bean生命周期的起点,主要涉及到Bean的定义和配置。在这个阶段,开发者通过XML、注解或Java配置等方式,定义Bean的类型、作用域、初始化方法、销毁方法等元信息。这些信息是Spring容器后续创建和管理Bean的依据。

功能点

  • 定义Bean的类型和名称
  • 指定Bean的作用域(如singleton、prototype等)
  • 配置Bean的初始化方法和销毁方法

底层原理

Spring容器通过解析配置信息,将这些信息转换为BeanDefinition对象,保存在BeanDefinitionRegistry中。BeanDefinition对象包含了Bean的所有元信息,是Bean生命周期后续阶段的基础。

2. Bean元信息解析阶段

背景与应用场景

在Bean元信息配置完成后,Spring容器需要对这些信息进行解析,以便后续创建和管理Bean。这个阶段主要涉及到对XML、注解或Java配置等信息的解析。

功能点

  • 解析XML配置文件中的<bean>标签
  • 解析注解(如@Component、@Service等)
  • 解析Java配置类中的@Bean方法

底层原理

Spring容器使用BeanDefinitionReader接口的实现类(如XmlBeanDefinitionReader)来解析配置信息,将这些信息转换为BeanDefinition对象,并注册到BeanDefinitionRegistry中。

3. 将Bean注册到容器中

背景与应用场景

在解析完Bean元信息后,需要将这些信息注册到Spring容器中,以便后续创建和管理Bean。

功能点

  • 将BeanDefinition对象注册到BeanDefinitionRegistry中

底层原理

Spring容器通过BeanDefinitionRegistry接口的实现类(如DefaultListableBeanFactory)来管理注册的BeanDefinition对象。这些对象在后续创建Bean时会被使用。

4. BeanDefinition合并阶段

背景与应用场景

在某些情况下,可能会有多个BeanDefinition对象定义同一个Bean。在这个阶段,Spring容器需要对这些BeanDefinition对象进行合并,以确定最终的Bean定义。

功能点

  • 合并多个BeanDefinition对象为一个

底层原理

Spring容器通过比较BeanDefinition对象的各个属性,如class、scope、lazy-init等,来确定最终的Bean定义。合并后的BeanDefinition对象将用于后续的Bean创建和管理。

5. Bean Class加载阶段

背景与应用场景

在创建Bean实例之前,需要先加载Bean对应的Class对象。这个阶段主要涉及到类加载器的使用。

功能点

  • 加载Bean对应的Class对象

底层原理

Spring容器使用Java的类加载机制来加载Bean对应的Class对象。这个过程可能涉及到自定义类加载器的使用,以满足特定的需求。

6. Bean实例化阶段

背景与应用场景

Bean实例化阶段是创建Bean实例的过程。在这个阶段,Spring容器根据BeanDefinition对象中的信息,使用反射机制来创建Bean实例。

功能点

  • 使用反射机制创建Bean实例

底层原理

Spring容器通过BeanDefinition对象中的class属性来获取Bean的完整类名,然后使用反射机制(如Class.forName()、Constructor.newInstance()等)来创建Bean实例。

7. 合并后的BeanDefinition处理

背景与应用场景

在Bean实例化之后,可能还需要对合并后的BeanDefinition对象进行一些处理,如设置Bean的属性、调用Bean的初始化方法等。

功能点

  • 设置Bean的属性
  • 调用Bean的初始化方法

底层原理

Spring容器通过BeanDefinition对象中的属性信息来设置Bean的属性值。对于初始化方法,Spring容器会在Bean实例化后调用这些方法(如通过实现InitializingBean接口或注解@PostConstruct指定的方法)。

8. 属性赋值阶段

背景与应用场景

属性赋值阶段是为Bean的属性设置值的过程。在这个阶段,Spring容器会根据BeanDefinition对象中的属性信息来设置Bean的属性值。

功能点

  • 设置Bean的属性值

底层原理

Spring容器通过反射机制来访问Bean的属性设置器(setter方法),并使用BeanDefinition对象中的属性值来调用这些方法。对于依赖注入的情况,Spring容器会先创建依赖的Bean实例,然后再设置这些依赖关系。

9. Bean初始化阶段

背景与应用场景

Bean初始化阶段是在Bean实例化并完成属性赋值后进行的。在这个阶段,Spring容器会调用Bean的初始化方法,执行一些必要的初始化操作。

功能点

  • 调用Bean的初始化方法

底层原理

Spring容器通过实现InitializingBean接口或注解@PostConstruct指定的方法来调用Bean的初始化方法。这些方法可以在Bean实例化后执行一些必要的初始化操作,如加载资源、初始化连接池等。

10. 所有单例Bean初始化完成后阶段

背景与应用场景

在所有单例Bean初始化完成后,Spring容器会执行一些额外的操作,如触发事件通知、初始化其他组件等。

功能点

  • 执行额外操作,如触发事件通知、初始化其他组件

底层原理

Spring容器通过事件发布机制来通知其他组件单例Bean初始化完成的事件。同时,也可以在这个阶段执行一些自定义的初始化操作。

11. Bean的使用阶段

背景与应用场景

Bean的使用阶段是指Bean被应用程序使用的过程。在这个阶段,Bean可以被其他Bean或组件引用和调用。

功能点

  • 提供Bean实例给其他组件使用

底层原理

Spring容器通过getBean()方法或其他依赖注入机制来提供Bean实例给其他组件使用。这些Bean实例可以在应用程序中被多次引用和调用。

12. Bean销毁前阶段

背景与应用场景

Bean销毁前阶段是在Bean被销毁之前进行的。在这个阶段,Spring容器会执行一些必要的清理操作,如关闭资源、释放连接等。

功能点

  • 执行清理操作,如关闭资源、释放连接

底层原理

Spring容器通过实现DisposableBean接口或注解@PreDestroy指定的方法来执行Bean销毁前的清理操作。这些方法可以在Bean被销毁之前执行一些必要的清理操作。

13. Bean销毁阶段

背景与应用场景

Bean销毁阶段是Bean生命周期的终点。在这个阶段,Spring容器会销毁Bean实例,释放资源。

功能点

  • 销毁Bean实例,释放资源

底层原理

Spring容器通过调用Bean的销毁方法(如通过实现DisposableBean接口或注解@PreDestroy指定的方法)来销毁Bean实例。同时,也会释放与Bean实例相关联的资源(如内存、数据库连接等)。

实战demo示例

下面是一个使用Java语言编写的Spring框架Bean生命周期的实战demo示例。

1. 定义Bean类

java复制代码
import org.springframework.beans.factory.DisposableBean;  
import org.springframework.beans.factory.InitializingBean;  
import org.springframework.stereotype.Component;  
import javax.annotation.PostConstruct;  
import javax.annotation.PreDestroy;  
@Component
public class MyBean implements InitializingBean, DisposableBean {  
public MyBean() {  
        System.out.println("Bean实例化阶段");  
    }  
@PostConstruct
public void init() {  
        System.out.println("Bean初始化阶段(@PostConstruct)");  
    }  
@Override
public void afterPropertiesSet() throws Exception {  
        System.out.println("Bean初始化阶段(InitializingBean接口)");  
    }  
public void myMethod() {  
        System.out.println("Bean使用阶段");  
    }  
@PreDestroy
public void destroy() {  
        System.out.println("Bean销毁前阶段(@PreDestroy)");  
    }  
@Override
public void destroy() throws Exception {  
        System.out.println("Bean销毁阶段(DisposableBean接口)");  
    }  
}

2. 配置Spring容器

java复制代码
import org.springframework.context.annotation.AnnotationConfigApplicationContext;  
import org.springframework.context.annotation.ComponentScan;  
import org.springframework.context.annotation.Configuration;  
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {  
}

3. 编写测试代码

java复制代码
import org.springframework.context.annotation.AnnotationConfigApplicationContext;  
public class Main {  
public static void main(String[] args) {  
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);  
// 获取Bean实例  
MyBean myBean = context.getBean(MyBean.class);  
// 调用Bean的方法  
        myBean.myMethod();  
// 关闭Spring容器  
        context.close();  
    }  
}

4. 运行结果

运行上述代码,将会输出:

复制代码
Bean实例化阶段  
Bean初始化阶段(@PostConstruct)  
Bean初始化阶段(Initializing
相关文章
|
5月前
|
XML Java 数据格式
SpringBean的生命周期
SpringBean的生命周期
59 0
|
5月前
|
XML Java 数据格式
Spring 应用上下文探秘:生命周期解析与最佳实践
Spring 应用上下文探秘:生命周期解析与最佳实践
107 0
|
11月前
|
Java Spring 容器
Spring源码:Bean的生命周期(二)
FactoryBean 和 BeanFactory 是两个不同的概念。前者是一个接口,我们可以在实现该接口时通过调用 getObject 方法来返回实例,同时 FactoryBean 本身也是一个实例。后者是 Spring 容器的工厂,通过其中的 bean 定义 Map 一个一个地实例化我们通过注解等方式注入进去的 bean 工厂。在判断 FactoryBean 时,如果当前 BeanFactory 中没有对应的 bean 定义,那么就会去父容器中寻找相应的 bean 定义并进行判断。如果我们的类实现了 SmartFactoryBean 接口,那么它将会在 Spring 容器启动时就会调用 g
|
11月前
|
Java 程序员 Spring
一文读懂 Bean的生命周期
一文读懂 Bean的生命周期
123 0
|
1月前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
106 24
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
11月前
|
存储 缓存 Java
Spring源码:Bean生命周期(三)
在之前的文章中,我们已经对 `bean` 的准备工作进行了讲解,包括 `bean` 定义和 `FactoryBean` 判断等。在这个基础上,我们可以更加深入地理解 `getBean` 方法的实现逻辑,并在后续的学习中更好地掌握`createBean` 方法的实现细节。
Spring源码:Bean生命周期(三)
|
11月前
|
XML Java 测试技术
Spring源码:bean的生命周期(一)
Spring的Bean定义环节是Spring IoC容器中的核心流程之一。在这个过程中,Spring会扫描指定的包路径,找到符合条件的Bean,并将其转换为Bean定义。在这个过程中,Spring使用了ASM技术来解析类的注解信息,判断当前类是否符合要求。然后,Spring将符合条件的Bean定义加入到候选集合中,并对其进行唯一标识命名、默认值赋值、常见定义注解的解析等操作。最后,Spring使用合并的Bean定义来包装原始的Bean定义,以便在Bean实例化的过程中进行更好的管理和控制。
Spring源码:bean的生命周期(一)
|
5月前
|
缓存 前端开发 Java
【Spring 源码】 贯穿 Bean 生命周期的核心类之 AbstractAutowireCapableBeanFactory
【Spring 源码】 贯穿 Bean 生命周期的核心类之 AbstractAutowireCapableBeanFactory
|
11月前
|
XML Java 数据格式
Spring源码:Bean生命周期(五)
在今天的文章中,我们将深入探讨 Bean 的属性注入和初始化流程,从而使其成为一个真正意义上的 Bean。这个过程包括属性注入、Aware 接口回调、BeanPostProcessor 的前置和后置处理等多个步骤,通过本文的学习,读者将能够更深入地了解 Spring 框架中 Bean 的属性注入和初始化过程,为后续的学习和实践打下坚实的基础。
|
11月前
|
缓存 前端开发 Java
Spring源码:Bean生命周期(四)
在本文中,我们深入探讨了 Spring 框架中 Bean 的实例化过程,关于某些细节以后我会单独拿出一篇文章单独讲解,我们来总结下实例化都做了哪些事情:先从bean定义中加载当前类,因为最初Spring使用ASM技术解析元数据时只获取了当前类的名称寻找所有InstantiationAwareBeanPostProcessors实现类,并调用实例化前的方法postProcessBeforeInstantiation进行实例化,这里会使用构造方法进行实例化调用applyMergedBeanDefinitionPostProcessors找到所有MergedBeanDefinitionPostPro