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)

(三)使用

(四)销毁

相关推荐
m0_743048444 小时前
Spring MVC练习
java·spring·mvc
小蒜学长6 小时前
校园周边美食探索及分享平台
java·spring boot·后端·spring·apache·美食
Wx-bishekaifayuan8 小时前
PHP动物收容所管理系统-计算机设计毕业源码94164
java·css·spring boot·spring·spring cloud·servlet·php
古城小栈11 小时前
Spring Security 认证流程,长话简说
java·python·spring
wmxz52012 小时前
SpringMVC处理请求流程
java·spring boot·后端·spring·java-ee
tian-ming18 小时前
JavaWeb后端开发案例——苍穹外卖day01
spring boot·spring
xybm160518 小时前
MTSET可溶于DMSO、DMF、THF等有机溶剂,并在水中有轻微的溶解性,91774-25-3
java·spring·eclipse·tomcat·1024程序员节
dream_ready18 小时前
四万字长文SpringBoot、Spring、SpringMVC等相关面试题(注:该篇博客将会持续维护 最新维护时间:2024年11月12日)
java·spring boot·后端·spring·面试·1024程序员节
张铁铁是个小胖子19 小时前
显示微服务间feign调用的日志
java·spring·微服务
Beekeeper&&P...19 小时前
spring中r类是什么
spring·r语言