Spring生命周期详解(4大步骤详细图解)

Spring生命周期详解(4大步骤详细图解)-mikechen

Spring生命周期主要分为以下4大阶段实例化、属性赋值、初始化阶段、销毁阶段,下面我一一详解@mikechen

Spring生命周期详解(4大步骤详细图解)-mikechen

第一步:实例化阶段

Spring生命周期详解(4大步骤详细图解)-mikechen

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。

下面我们结合代码来直观的看下,在 doCreateBean() 方法中:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
 
    // 1. 实例化Bean
    BeanWrapper instanceWrapper = null;
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }

这里的createBeanInstance就是实例化Bean的入口,这一步仅仅是简单的实例化,并未进行依赖注入。

 

第二步:Bean属性赋值

Spring生命周期详解(4大步骤详细图解)-mikechen

实例化对象被包装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息以及通过BeanWrapper提供的设置属性的接口完成依赖注入。

下面我们结合代码来直观的看下:

// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
 
    // 1. 实例化Bean
    BeanWrapper instanceWrapper = null;
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
   
    Object exposedObject = bean;
    try {
        // 2. Bean属性赋值
        populateBean(beanName, mbd, instanceWrapper);

依然在 doCreateBean() 方法中,上面我注释的第2个步骤Bean属性赋值:populateBean这个方法就是属性注入入口。

 

第三步:初始化阶段

Spring生命周期详解(4大步骤详细图解)-mikechen

初始化阶段主要是在返回Bean之前做一些处理,主要由initializeBean()方法实现。

依然在 doCreateBean() 方法中,下面我注释的第3个步骤就是初始化,如下所示:

// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
 
    // 1. Bean实例化
    BeanWrapper instanceWrapper = null;
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
   
    Object exposedObject = bean;
    try {
        // 2. Bean属性赋值
        populateBean(beanName, mbd, instanceWrapper);
        // 3. 初始化Bean
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }

initializeBean初始化的过程会较多,所以我们进到 initializeBean() 方法里具体看下其过程。

如下所示:

1. BeanPostProcessor 前置处理 

if(mbd == null || !mbd.isSynthetic())
{
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
} 

2. 若实现 InitializingBean 接口, 调用 afterPropertiesSet() 方法 

3. 若配置自定义的 init - method方法, 则执行
try
{
    invokeInitMethods(beanName, wrappedBean, mbd);
}
catch(Throwable ex)
{
    throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex);
} //

4. BeanPostProceesor 后置处理
if(mbd == null || !mbd.isSynthetic())
{
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;

主要包含以下几大流程:

1.BeanPostProcessor前置处理 

当经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现。

1. BeanPostProcessor 前置处理 

if(mbd == null || !mbd.isSynthetic())
{
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

postProcessBeforeInitialzation:这个函数会先于InitialzationBean执行,因此称为前置处理。

 

2.InitializingBean 与init-method自定义方法

当BeanPostProcessor的前置处理完成后就会进入本阶段。

如果Bean在Spring配置文件中配置了init-method属性,则会自动调用其配置的初始化方法。

 

3.BeanPostProceesor 后置处理

postProcessAfterInitialzation: 这个函数会在InitialzationBean完成后执行,因此称为后置处理。

4. BeanPostProceesor 后置处理
if(mbd == null || !mbd.isSynthetic())
{
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

通过以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。

 

第四步:销毁阶段

Spring生命周期详解(4大步骤详细图解)-mikechen

当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;

最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

 

作者简介

陈睿|mikechen,10年+大厂架构经验,BAT资深面试官,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

👇阅读更多mikechen架构文章👇

阿里架构 |双11秒杀 |分布式架构 |负载均衡 |单点登录 |微服务 |云原生 |高并发 |架构师

以上

关注作者「mikechen」公众号,获取更多技术干货!

后台回复架构,即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法