springBean生命周期解析

本文基于Spring5.3.7

参考:kykangyuky Spring中bean的生命周期
阿斌Java之路 SpringBean的生命周期

杨开振 JavaEE互联网轻量级框架整合开发

黑马程序员 JavaEE企业级应用开发教程

马士兵 Spring源码讲解

一. SpringBean生命周期流程图

二. 示例代码

1. 定义果汁描述实体类

java 复制代码
package com.xiaobai.spring_bean_life_cycle;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @author wangtw
 * @date 2023/6/24 16:38
 * @description 果汁描述实体类
 */
@Slf4j
@Data
public class Source {

    public Source() {
        log.info("source实例化");
    }

    /**
     * 水果
     */
    private String fruit;

    /**
     * 糖量
     */
    private String sugar;

    /**
     * 大小
     */
    private String size;
}

2. 定义果汁生成器

java 复制代码
package com.xiaobai.spring_bean_life_cycle;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @author wangtw
 * @date 2023/6/24 16:28
 * @description 果汁生成器
 */
@Slf4j
@Data
public class JuiceMaker implements BeanNameAware, BeanFactoryAware,
        ApplicationContextAware, InitializingBean, DisposableBean {

    public JuiceMaker(){
        log.info("juice实例化");
    }

    private String beverageShop;

    private Source source;

    /**
     * 自定义初始化方法
     */
    public void init() {
        log.info("【{}】执行自定义初始化方法", this.getClass().getSimpleName());
    }

    /**
     * 自定义销毁方法
     */
    public void myDestroy() {
        log.info("【{}】执行自定义销毁方法", this.getClass().getSimpleName());
    }

    public String makeJuice() {
        String juice = "这是一杯由" + beverageShop + "饮品店,提供的" + source.getSize() + source.getSugar() + source.getFruit();
        return juice;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.info("【{}】调用BeanFactoryAware接口的setBeanFactory方法", this.getClass().getSimpleName());
    }

    @Override
    public void setBeanName(String s) {
        log.info("【{}】调用BeanNameAware接口的setBeanName方法", this.getClass().getSimpleName());
    }

    @Override
    public void destroy() throws Exception {
        log.info("调用接口DisposableBean的destroy方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("【{}】调用InitializingBean接口的afterPropertiesSet方法", this.getClass().getSimpleName());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("【{}】调用ApplicationContextAware接口的setApplicationContext方法", this.getClass().getSimpleName());
    }
}

3. 定义Bean实现BeanPostProcessor接口

java 复制代码
package com.xiaobai.spring_bean_life_cycle;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @author wangtw
 * @date 2023/6/24 16:07
 * @description
 */
@Slf4j
public class BeanPostProcessorImpl implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        log.info("【{}】对象{}预初始化开始", bean.getClass().getSimpleName(), beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        log.info("【{}】对象{}预初始化完成", bean.getClass().getSimpleName(), beanName);
        return bean;
    }
}

4. 定义SpringBean配置类

java 复制代码
package com.xiaobai.spring_bean_life_cycle;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author wangtw
 * @date 2023/6/25 10:33
 * @description Spring配置类
 */
@Configuration
public class LifeConfiguration {

    @Bean("beanPostProcessor")
    public BeanPostProcessor beanPostProcessor() {
        return new BeanPostProcessorImpl();
    }

    @Bean("source")
    public Source source() {
        Source source = new Source();
        source.setFruit("橙汁");
        source.setSugar("少糖");
        source.setSize("大杯");
        return source;
    }

    @Bean(value = "juiceMaker", initMethod = "init", destroyMethod = "myDestroy")
    public JuiceMaker juiceMaker() {
        JuiceMaker juiceMaker = new JuiceMaker();
        juiceMaker.setSource(source());
        juiceMaker.setBeverageShop("贡茶");
        return juiceMaker;
    }
}

5. 测试类及输出结果

java 复制代码
package com.xiaobai.spring_bean_life_cycle;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author wangtw
 * @date 2023/6/25 10:40
 * @description springBean生命周期测试类
 */
@Slf4j
public class SpringBeanLifeTest {

    @Test
    public void testLifeCycle() {
        ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(LifeConfiguration.class);
        JuiceMaker juiceMaker = (JuiceMaker) context.getBean("juiceMaker");
        log.info(juiceMaker.makeJuice());
        context.close();
    }
}

三. 源码解析

(一)Bean实例化

1. 根据注解加载Bean

org.springframework.beans.factory.config.BeanFactoryPostProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)
org.springframework.context.annotation.ConfigurationClassParser#parse(org.springframework.core.type.AnnotationMetadata, java.lang.String)
org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClass
org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass

2. 在SpringBean实例化前会把扫描到的类加载到BeanDefinition中,然后将BeanDefinition中的信息注册到Spring容器中

org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()
org.springframework.context.annotation.AnnotationConfigApplicationContext#register
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
org.springframework.beans.factory.support.BeanDefinitionRegistry#registerBeanDefinition

3. 完成了BeanDefinition注册后,对Bean进行实例化

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

(二)初始化

1. 属性赋值

(1)自定义对象属性赋值

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

(2)容器对象赋值:检查aware接口并设置相关依赖(aware接口用于标记,判断调用什么方法)

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

2. 执行前置处理方法

org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization

3. 执行初始化方法

(1)检测Bean是否实现了InitializingBean接口

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

(2)调用afterPropertiesSet方法

org.springframework.beans.factory.InitializingBean#afterPropertiesSet

(3)调用自定义初始化方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeCustomInitMethod

4. 执行后置处理方法

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

创建代理对象
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

org.springframework.aop.framework.AopProxy#getProxy(java.lang.ClassLoader)

(三)使用

(四)销毁

相关推荐
北极无雪3 小时前
Spring源码学习(拓展篇):SpringMVC中的异常处理
java·开发语言·数据库·学习·spring·servlet
Amagi.4 小时前
Spring中Bean的作用域
java·后端·spring
J老熊4 小时前
Spring Cloud Netflix Eureka 注册中心讲解和案例示范
java·后端·spring·spring cloud·面试·eureka·系统架构
TheManba5 小时前
04. maven 三种项目打包方式 pom、jar、war 的区别(记一次 Spring 项目启动报错)
spring·maven·jar
努力的布布5 小时前
SpringMVC源码-AbstractHandlerMethodMapping处理器映射器将@Controller修饰类方法存储到处理器映射器
java·后端·spring
xujinwei_gingko5 小时前
Spring MVC 常用注解
java·spring·mvc
LearnTech_1235 小时前
【学习笔记】手写一个简单的 Spring MVC
笔记·学习·spring·spring mvc
PacosonSWJTU6 小时前
spring揭秘26-springmvc06-springmvc注解驱动的web应用
java·spring·springmvc
Leanfeng_K7 小时前
【报错】mac m1 gateway 报错
spring·macos·spring cloud·gateway·报错
Nightselfhurt9 小时前
Spring cloud 中gateway原理
spring·spring cloud·gateway