Spring中Bean的生命周期源码分析

前面的梳理中已经将Spring的容器的创建、Bean的创建、BeanPostProcessor的使用、ApplicationListener的使用、代理模式梳理完成,其实以上的所有的梳理都是Spring的Bean声明周期的细节,现在从整体上分析一下Spring中Bean声明周期是如何实现的。

以下的分析会从容器的启动、注解如何加载Bean、创建BeanDefinition、容器的刷新(核心)、创建Bean、销毁Bean的链路梳理,从源头了解Bean的生命周期。 

容器启动流程

容器启动流程就是我们平时使用SpringBoot的启动类,在启动类中都会有一段SpringApplication.run(DispatchAdapterApplication.class, args) 代码,这段代码就是启动Spring服务的调用。在这段代码中启动了Spring应用,那么其中又是如何启动Spring容器,并且启动过程中如何将Bean注入到容器中的呢?从源码中梳理整个过程。

容器启动流程:

  1. 创建应用上下文接口ConfigurableApplicationContext,该接口可以理解为是最顶级的接口,该接口中提供了设置Spring环境、设置BeanFactoryPostProcessor、ApplicationListener、注册Bean、销毁Bean的所有方法,该接口是提供给应用启动程序使用,并且主要使用在启动和关闭阶段。
//Spring启动实现类
public class SpringApplication {

    //注解的方式注入类的实现
    public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
    + "annotation.AnnotationConfigApplicationContext";


    
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                                                                     applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            //创建AnnotationConfigApplicationContext实现类
            context = createApplicationContext();
            exceptionReporters = getSpringFactoriesInstances(
                SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class }, context);
            //对AnnotationConfigApplicationContext的准备逻辑,设置环境、监听器等
            prepareContext(context, environment, listeners, applicationArguments,
                           printedBanner);
            //调用容器刷新逻辑
            refreshContext(context);
            //刷新之后的处理,开发者可以重写该方法做后续的处理
            afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                    .logStarted(getApplicationLog(), stopWatch);
            }
            listeners.started(context);
            callRunners(context, applicationArguments);
        }
        .....
        return context;
    }


    protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
					contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
					break;
				case REACTIVE:
					contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
					break;
				default:
                    //默认会调用这个实例化AnnotationConfigApplicationContext
					contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
				}
			}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值