前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解读spring5源码中实例化单例bean的调用链

解读spring5源码中实例化单例bean的调用链

作者头像
公众号:码到三十五
修改2024-03-21 08:57:22
1030
修改2024-03-21 08:57:22
举报
文章被收录于专栏:JAVA核心

在 Spring 5 的源码中,实例化单例 Bean 的调用链可以从 Spring Boot 的主类 SpringApplication 的 run 方法开始。

下是大致的调用链路:

1. SpringApplication.run 方法

这是 Spring Boot 应用程序启动的入口方法。它创建了一个新的 Spring 应用上下文,并启动了应用程序。

2. SpringApplication.refreshContext 方法

该方法在 run 方法内部被调用,用于完成应用上下文的初始化和刷新。

3. AbstractApplicationContext.refresh 方法

这是 Spring Framework 中 ApplicationContext 接口的实现类的方法。它负责完成应用上下文的刷新过程。

4. AbstractApplicationContext.obtainFreshBeanFactory 方法

该方法负责创建或获取新的 BeanFactory 实例,BeanFactory 是 Spring IoC 容器的核心。如果已经存在 BeanFactory 实例,则会重用。

5. AbstractApplicationContext.refreshBeanFactory 方法

该方法使用在步骤4中获取的 BeanFactory 实例进行应用上下文的配置和初始化。

6. AbstractApplicationContext.preInstantiateSingletons 方法

该方法用于预实例化所有的单例 Bean。

代码语言:javascript
复制
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}
7. AbstractBeanFactory.preInstantiateSingletons 方法

该方法负责遍历容器中的所有 BeanDefinition,检查是否是单例模式,并执行相应的实例化操作。

8. DefaultListableBeanFactory.preInstantiateSingletons 方法

此方法继承自 AbstractBeanFactory.preInstantiateSingletons,它实际上会调用 AbstractBeanFactory.doGetBean 方法来创建单例 Bean 的实例。

代码语言:javascript
复制
  public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Pre-instantiating singletons in " + this);
        }

        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();

        while(true) {
            String beanName;
            Object bean;
            do {
                while(true) {
                    RootBeanDefinition bd;
                    do {
                        do {
                            do {
                                if (!var2.hasNext()) {
                                    var2 = beanNames.iterator();

                                    while(var2.hasNext()) {
                                        beanName = (String)var2.next();
                                        Object singletonInstance = this.getSingleton(beanName);
                                        if (singletonInstance instanceof SmartInitializingSingleton) {
                                            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                            if (System.getSecurityManager() != null) {
                                                AccessController.doPrivileged(() -> {
                                                    smartSingleton.afterSingletonsInstantiated();
                                                    return null;
                                                }, this.getAccessControlContext());
                                            } else {
                                                smartSingleton.afterSingletonsInstantiated();
                                            }
                                        }
                                    }

                                    return;
                                }

                                beanName = (String)var2.next();
                                bd = this.getMergedLocalBeanDefinition(beanName);
                            } while(bd.isAbstract());
                        } while(!bd.isSingleton());
                    } while(bd.isLazyInit());

                    if (this.isFactoryBean(beanName)) {
                        bean = this.getBean("&" + beanName);
                        break;
                    }

                    this.getBean(beanName);
                }
            } while(!(bean instanceof FactoryBean));

            FactoryBean<?> factory = (FactoryBean)bean;
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                SmartFactoryBean var10000 = (SmartFactoryBean)factory;
                ((SmartFactoryBean)factory).getClass();
                isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
            } else {
                isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
            }

            if (isEagerInit) {
                this.getBean(beanName);
            }
        }
    }
10. AbstractBeanFactory.doGetBean 方法

该方法是获取 Bean 实例的核心方法,其中包括了解决循环依赖、实例化 Bean 对象和执行初始化操作等逻辑。

11. AbstractAutowireCapableBeanFactory.createBean 方法

该方法是 AbstractBeanFactory.doGetBean 方法的一个关键步骤,用于创建 Bean 实例。它会调用相关的实例化策略和处理器来创建 Bean 对象。

12. AbstractAutowireCapableBeanFactory.instantiateBean 方法

该方法使用实例化策略(InstantiationStrategy)来实例化 Bean 对象,具体的实例化策略根据不同情况可能会有所不同。

13. SimpleInstantiationStrategy.instantiate 方法:

这是 Spring 默认的实例化策略,默认使用反射来实例化 Bean 对象。

以上是大致的调用链,详细的实现细节可能因版本和具体配置而有所不同。在整个过程中,Spring 通过调用一系列的方法和处理器,完成了单例 Bean 的实例化和初始化工作,最终将可用的单例 Bean 放入容器中供其他组件使用。


术因分享而日新,每获新知,喜溢心扉。 诚邀关注公众号 码到三十五 ,获取更多技术资料。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. SpringApplication.run 方法
  • 2. SpringApplication.refreshContext 方法
  • 3. AbstractApplicationContext.refresh 方法
  • 4. AbstractApplicationContext.obtainFreshBeanFactory 方法
  • 5. AbstractApplicationContext.refreshBeanFactory 方法
  • 6. AbstractApplicationContext.preInstantiateSingletons 方法
  • 7. AbstractBeanFactory.preInstantiateSingletons 方法
  • 8. DefaultListableBeanFactory.preInstantiateSingletons 方法
  • 10. AbstractBeanFactory.doGetBean 方法
  • 11. AbstractAutowireCapableBeanFactory.createBean 方法
  • 12. AbstractAutowireCapableBeanFactory.instantiateBean 方法
  • 13. SimpleInstantiationStrategy.instantiate 方法:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档