3分钟秒懂,最简单通俗易懂的spring bean 生命周期介绍与源码分析,附上demo完整源码

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章写作背景

最近突然身边很多小伙伴问我有没有spring bean生命周期的通俗移动的介绍
起初不太理解为什么后来才想明白哦对了年底了快开始跳槽季了这不就是java八股文面试
的题目嘛不得不说国内真的很卷之前有认识的外国友人人家说面试根本不会问这些基本就是
问问做过哪些项目功能模块就完事了主要是试用期去衡量他的能力好了闲话少说我们开始
正式聊一聊spring bean 的生命周期本文不涉及循环依赖以及三级缓存问题如果需要的话我可以后续有时间的时候单独写一篇介绍本文只针对bean的生命周期尽量用最简化的方式描述

为什么大家有时候觉得spring bean的生命周期繁琐

其实我觉得大家是把主流程和分支流程搞一起了网上大部分文章都是混在一起介绍的比如创建实例createBeanInstance之前会执行
InstantiationAwareBeanPostProcessor的postProcessBeforeInitialization方法
创建之后还会执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法然后执行 InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
其实这些大家不需要和主流程混在一起记忆因为这些都是辅助分支流程因为可能你定义多少
实现类那就是多少辅助流程循环执行

真正的spring bean 主生命周期

其实真正的spring bean 生命周期大家只要记住是生成实例->填充属性->初始化->销毁就可以了

如何记忆before after merge等辅助流程

为了方便大家记忆我特意画了一个流程图主流程和辅助流程是分开的一目了然再结合我下面的demo跑一下程序或者自己写一个验证一下就可以了如图下
在这里插入图片描述

创建简单demo 实现各个辅助接口完整源码

目录结构

在这里插入图片描述

pom引用

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.5.RELEASE</version>
            <scope>compile</scope>
        </dependency>

创建空项目,引入spring-contenxt为什么引入context,因为它包含了spring framework 基本的所有依赖pom

Application.java

/**
 * @Author alan.wang
 */
public class Application {

    public static Integer index = 0;

    public static void main(String[] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Teacher teacher = context.getBean(Teacher.class);
        System.out.println("class:" + teacher.name());
    }
}

Teacher.java 以及TeacherImpl.java 实现类
TeacherImpl 实现了上图那些接口InitializingBean,BeanNameAwareBeanClassLoaderAwareBeanFactoryAwareDisposableBean

/**
 * @Author alan.wang
 */
public interface Teacher {
    String name();
}


/**
 * @Author alan.wang
 */
@Service
public class TeacherImpl implements Teacher  , InitializingBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware , DisposableBean {


    public String name() {
        return "teacher";
    }


    @PostConstruct
    public void init(){
        System.out.println(++Application.index+" postConstruct");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println(++Application.index+" afterPropertiesSet");
    }

    public void setBeanName(String name) {
        System.out.println(++Application.index+" setBeanName");
    }

    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println(++Application.index+" setBeanClassLoader");
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println(++Application.index+" setBeanFactory");
    }


    @Override
    public void destroy() throws Exception {
        System.out.println(++Application.index+" destroy");

    }
}

PrintAwareBeanPostProcessor.java
PrintAwareBeanPostProcessor实现了InstantiationAwareBeanPostProcessor 接口主要是对类创建实例前和后的包装
这里就是单纯地输出证明执行了

/**
 * @Author alan.wang
 */
@Service
public class PrintAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println(++Application.index+" InstantiationAwareBeanPostProcessor-postProcessBeforeInstantiation:"+beanName);
        return null;
    }

    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println(++Application.index+" InstantiationAwareBeanPostProcessor-postProcessAfterInstantiation:"+beanName);

        return true;
    }

    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println(++Application.index+ " InstantiationAwareBeanPostProcessor-postProcessProperties:"+beanName);

        return pvs;
    }
}

PrintMergedBeanDefinitionPostProcessor.java
PrintMergedBeanDefinitionPostProcessor
实现了MergedBeanDefinitionPostProcessor 接口主要是对实例化后的bean进行自定义的mergec处理
这里仅仅是对方法进行输出

/**
 * @Author alan.wang
 */
@Component
public class PrintMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        System.out.println(++Application.index+" MergedBeanDefinitionPostProcessor-postProcessMergedBeanDefinition:"+beanName);
    }

    public void resetBeanDefinition(String beanName) {
        System.out.println(++Application.index+" MergedBeanDefinitionPostProcessor-resetBeanDefinition:"+beanName);

    }
}


> ***PrintBeanPostProcessor.java
> PrintBeanPostProcessor实现了BeanPostProcessor接口 BeanPostProcessor实际上是根接口InstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor都是它的子接口
> BeanPostProcessor 一般是对bean 初始化阶段的前后before 和after处理
> 这里也仅仅是方法输出***
/**
 * @Author alan.wang
 */
@Service
public class PrintBeanPostProcessor implements BeanPostProcessor  {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(++Application.index+" BeanPostProcessor-postProcessBeforeInitialization:"+beanName);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(++Application.index+" BeanPostProcessor-postProcessAfterInitialization:"+beanName);
        return bean;
    }
}

demo 执行结果与并对照上面的流程图来看源码

首先来看下执行输出执行顺序结果
在这里插入图片描述

我们看到首先执行的是InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法
该方法是在创建bean的实例之前的源码如下

在这里插入图片描述

然后是创建bean实例
在这里插入图片描述

然后是填属性也就是依赖注入
在这里插入图片描述

然后是MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
在这里插入图片描述

然后是InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
在这里插入图片描述

然后是InstantiationAwareBeanPostProcessor的postProcessProperties方法
在这里插入图片描述

然后是BeanNameAware的setBeanName 方法 然后是BeanClassLoaderAware的setBeanClassLoader方法
然后是BeanFactoryAware的setBeanFactory 方法他们可以看做是一体的

在这里插入图片描述

然后是BeanPostProcessor的postProcessBeforeInitialization方法
在这里插入图片描述

然后是@postConstruct注解的方法
在这里插入图片描述

然后是执行初始化函数
在这里插入图片描述

然后是InitializingBean的afterPropertiesSet方法
在这里插入图片描述

然後是BeanPostProcessor的postProcessAfterInitialization方法
在这里插入图片描述

然后是destory 相关destory实际上demo不会触发因为执行结束了主线程结束就关闭了需要一个CloseEvent消息需要添加addShutdownHook 这里暂时不做介绍
在这里插入图片描述

结束语

不要死记硬背不要被辅助流程干扰结合上述流程图去看源码跑遍demo基本就了解了

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring