解析Spring中Bean的生命周期

简介: 解析Spring中Bean的生命周期

解析Spring框架中Bean的生命周期不仅可以帮助我们更好地理解Spring的工作机制,还能让我们在实际开发中更加得心应手。Spring管理Bean的生命周期涉及多个步骤,从实例化到销毁,每一个步骤都有其独特的处理逻辑。本文将通过源码详细解析Spring中Bean的生命周期。

 

1. Bean的生命周期概述

 

Spring中Bean的生命周期包括以下几个主要阶段:

 

1. **实例化(Instantiation)**:创建Bean实例。

2. **属性填充(Populate properties)**:将依赖注入到Bean实例中。

3. **初始化(Initialization)**:调用初始化方法。

4. **使用(Usage)**:Bean处于就绪状态,供应用程序使用。

5. **销毁(Destruction)**:容器关闭时调用销毁方法。

 

这些阶段由不同的组件和机制来共同完成,如`BeanFactory`,`BeanPostProcessor`,以及各种回调接口等。

 

2. 实例化Bean

 

实例化过程由`AbstractAutowireCapableBeanFactory`类的`createBeanInstance`方法负责。它根据Bean定义信息选择合适的构造函数或工厂方法来创建Bean实例。

 

```java
protected Object createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 如果设置了工厂方法,则通过工厂方法创建Bean
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }
 
    // 尝试使用默认构造函数或带参数的构造函数
    Constructor<?> constructorToUse = null;
    synchronized (mbd.constructorArgumentLock) {
        constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
        if (constructorToUse == null) {
            final Class<?> beanClass = resolveBeanClass(mbd, beanName);
            if (beanClass != null) {
                if (!Modifier.isPublic(beanClass.getModifiers())) {
                    throw new BeanCreationException(
                            beanName, "Bean class isn't public, and non-public classes not supported: " + beanClass.getName());
                }
                try {
                    constructorToUse = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    mbd.resolvedConstructorOrFactoryMethod = constructorToUse;
                } catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
                }
            }
        }
    }
    return instantiateBean(beanName, mbd, constructorToUse);
}
```

 

该方法首先检查Bean定义中是否指定了工厂方法,如果有则通过工厂方法创建Bean实例;否则,尝试使用默认构造函数或带参数的构造函数。

 

3. 属性填充

 

一旦Bean实例创建完成,Spring会将依赖注入到该实例中。这一步由`populateBean`方法负责。

 

```java
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    beanName, "Cannot apply property values to null instance");
        } else {
            // Skip property population phase for an existing null instance.
            return;
        }
    }
 
    // 应用 InstantiationAwareBeanPostProcessors
    boolean continueWithPropertyPopulation = true;
 
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessors(InstantiationAwareBeanPostProcessor.class)) {
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                continueWithPropertyPopulation = false;
                break;
            }
        }
    }
 
    if (!continueWithPropertyPopulation) {
        return;
    }
 
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
 
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
 
    // 应用 BeanPostProcessors 修改属性值
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
 
    if (hasInstAwareBpps || needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessors(InstantiationAwareBeanPostProcessor.class)) {
                PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (pvs == null) {
                        pvs = mbd.getPropertyValues();
                    }
                    pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
        if (needsDepCheck) {
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }
 
    // 将属性值应用到 Bean 实例
    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}
```

 

`populateBean`方法首先应用`InstantiationAwareBeanPostProcessor`接口的`postProcessAfterInstantiation`方法,对Bean实例进行后续处理,接着根据自动装配模式(byName或byType)进行依赖注入,最后将属性值应用到Bean实例。

 

4. 初始化Bean

 

在属性填充完成后,Spring会调用Bean的初始化方法,这一步由`initializeBean`方法负责。

 

```java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessControlContext acc = getAccessControlContext();
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, acc);
    } else {
        invokeAwareMethods(beanName, bean);
    }
 
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
 
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex);
    }
 
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
 
    return wrappedBean;
}
```

 

`initializeBean`方法首先调用`invokeAwareMethods`方法处理实现了`Aware`接口的Bean,例如,如果Bean实现了`BeanNameAware`接口,则会调用`setBeanName`方法。接着,方法应用`BeanPostProcessor`接口的`postProcessBeforeInitialization`方法,然后调用Bean的初始化方法(如`@PostConstruct`注解的方法或自定义的初始化方法)。最后,应用`BeanPostProcessor`接口的`postProcessAfterInitialization`方法。

 

5. 销毁Bean

 

当容器关闭时,Spring会调用Bean的销毁方法,这一步由`destroyBean`方法负责。

 

```java
protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware).destroy();
}
```

 

`destroyBean`方法使用`DisposableBeanAdapter`来管理Bean的销毁过程。`DisposableBeanAdapter`会检查Bean是否实现了`DisposableBean`接口或定义了自定义的销毁方法,并调用相应的销毁方法。

 

总结

 

通过对Spring源码的详细分析,我们可以看到Spring是如何管理Bean的生命周期的:

 

1. **实例化**:通过反射机制创建Bean实例。

2. **属性填充**:将依赖对象注入到Bean实例中。

3. **初始化**:在属性填充完毕后调用初始化方法。

4. **销毁**:在容器关闭时调用销毁方法。

 

这种设计使得Spring能够灵活地管理Bean的生命周期,并提供了丰富的扩展点供开发者自定义Bean的创建和销毁逻辑。通过了解这些底层机制,我们可以更好地使用和扩展Spring框架,满足复杂应用的需求。

目录
相关文章
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
2933 1
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
925 26
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
531 5
|
XML Java 开发者
Spring底层架构核心概念解析
理解 Spring 框架的核心概念对于开发和维护 Spring 应用程序至关重要。IOC 和 AOP 是其两个关键特性,通过依赖注入和面向切面编程实现了高效的模块化和松耦合设计。Spring 容器管理着 Beans 的生命周期和配置,而核心模块为各种应用场景提供了丰富的功能支持。通过全面掌握这些核心概念,开发者可以更加高效地利用 Spring 框架开发企业级应用。
416 18
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
690 1
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
419 12
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
552 12
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
485 6

推荐镜像

更多
  • DNS