在 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。
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 的实例。
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 放入容器中供其他组件使用。