java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Bean初始化和生命周期

一文带你了解Spring的Bean初始化过程和生命周期

作者:归去来 兮

Spring的核心功能有三点IOC、DI、AOP,IOC则是基础,也是Spring功能的最核心的点之一。今天一起来总结下Spring中Bean是怎么被创建出来的

一、Spring创建bean的流程图

下图是笔者多次翻看IOC源码后总结出来的bean 创建的详细过程,借助该图可以很快的理解相关源码

二、Spring创建bean的详细流程

上面的流程图其实已经可以很清晰的看到bean的创建过程了,这里结合图片我们一起来详细说下这个过程,这里不贴源码,贴了源码只会让观看的人比较迷糊,若是想跟源码的可以对照上面的流程图完全能做到源码复现,bean创建的这个过程大致可以分为五步:加载bean信息,实例化bean,bean属性填充,初始化bean,后置操作,那我们就基于这五大步来看看Spring是如何创建bean的。

1.加载bean信息

被IOC注解修饰的类,或者通过xml配置的类,首先在容器启动时一refresh方法为入口,会将这些类扫描进来形成BeanDefinition信息,BeanDefinition就是包含了我们配置的一些bean的属性,比如是否单例,是否有bean依赖(DependOn),bean的名称,bean所属class的全路径等,这里存储的相当于bean的元信息,然后通过 BeanDefinitionRegistry将这些BeanDefinition加载进来后面我们就可以利用该信息了,且在Spring创建Bean的全程都需要BeanDefinition的参与,所以他很重要。

2.实例化bean

通过上面的图可以清晰看到在实例化阶段之前其实还有很多小的操作:容器会先去尝试getBean–>doGetBean–>getSingleton等操作在这些操作都拿不到对象以后才会开始着手创建对象,需要说的是getSingleton会尝试从三级缓存中依次去获取Bean,当所有缓存都获取不到时就可以确认当前bean没有被创建,然后就可以启动创建的相关动作

3.bean属性填充

属性填充其实就为自身属性进行赋值的过程,根据我们的DI注解这里会先从三个缓存中获取bean,若是获取不到,则会尝试进行bean的创建,若是走到了bean的创建,则会重新走一边bean创建的整个流程,这里是递归逻辑。

4.初始化bean

属性填充完毕后并没有立即结束这个过程,还有一些其他的操作需要spring进行处理,比如aware接口的处理,postprocessor接口的处理,初始化的处理等操作其实这里主要就是处理这三个动作的

5.后置操作

这里的后置操作,主要是完成一些清扫工作和适配工作,比如删除二级、三级缓存中无用的bean引用等,下面是具体操作。

看了这五步,不知道是不是对bean的创建过程有了清晰的认识,如果还是不够清晰可以根据第一部分的流程图走下代码,代码走两遍其实就会比较清晰了。

三、bean的生命周期

bean的生命周期其实就是从创建到销毁,上面创建已经说完了,其实只差销毁这一步了。bean销毁发生在容器关闭时对单例bean进行清除操作。在Spring中我们通常有三种方式定义bean销毁时的逻辑

1.通过PreDestroy注解修饰方法

Bean销毁时会检查有无该注解修饰的方法,如有,会对该注解修饰的方法进行执行

2.通过指定destroy-method方法

在使用xml对bean进行注入时,我们可以指定init-method方法,也可以指定destroy-method方法,同样的使用Bean注解时也是支持这两个属性的,Spring容器关闭时会寻找当前bean有无指定destroy-method,如有则会进行执行

3.实现DisposableBean接口

实现该接口重写他的destroy方法,同样的Spring容器关闭时也会检查有无实现该接口,如有实现也会执行这里的销毁方法

下面是对于三种销毁方式的测试代码

第一端是自定义Spring容器,给容器注册钩子,这样当我们关闭Spring容器时会自动调用我们的销毁方法

public class AppStartClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(yuCloseSpring.class);
        annotationConfigApplicationContext.start();
        annotationConfigApplicationContext.registerShutdownHook();
    }

这一段是测试代码了,分别使用三种方式写了销毁方法

public class MyDisposableBean  implements DisposableBean{


    @Override
    public void destroy() throws Exception {
        System.out.println("执行DisposableBean的销毁方法");

    }

    public void test(){
        System.out.println("执行destroy-method销毁方法");
    }

    @PreDestroy
    public void testPreDestroy(){
        System.out.println("执行PreDestroy注解修饰的销毁方法");
    }

}
@Configuration
class yuCloseSpring{

    @Bean(destroyMethod = "test")
    public MyDisposableBean getMyDisposableBean(){
        return  new MyDisposableBean();
    }
}

下面是启动main方法后的执行截图,可以清晰的看到三种销毁方法都是正常执行的,且他们执行顺序是固定的,即:PreDestroy–>DisposableBean–>destroy-method。

到这里其实bean整个生命周期就算是彻底结束了。

四、总结

这篇主要总结Spring中bean的创建过程,主要分为==加载bean信息–>实例化bean–>属性填充–>初始化阶段–>后置处理等步骤,且每个步骤Spring做的事情都很多,这块源码还是很值得我们都去看一看的。==而Spring中Bean的声明周期其实就是创建到使用到销毁,使用应该没啥需要说的,销毁在第三部分也正常介绍了三种销毁的方式。希望这一篇可以对路过的你有所帮助。

以上就是一文带你了解Spring的Bean初始化过程和生命周期的详细内容,更多关于Spring Bean初始化和生命周期的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文