springBean生命周期解析

本文基于Spring5.3.7

参考:
kykangyuky Spring中bean的生命周期

阿斌Java之路 SpringBean的生命周期
杨开振 JavaEE互联网轻量级框架整合开发
黑马程序员 JavaEE企业级应用开发教程
马士兵 Spring源码讲解

一. SpringBean生命周期流程图

SpringBean生命周期流程

二. 示例代码

1. 定义果汁描述实体类

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. 定义果汁生成器

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接口

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配置类

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. 测试类及输出结果

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)

(三)使用

(四)销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值